1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
//! Port of `hermes::sema::resolveAST` (`lib/Sema/SemResolve.cpp:163-195`) and
//! `resolveASTForParser` (`cpp:299-310`) — the two `SemResolve.h` entry
//! points this crate has.
//!
//! **Stability: stable.** The two functions here are the low-level entry
//! points under the crate-root façade, and are what a consumer needing more
//! control than [`crate::resolve()`] offers should call; see the crate doc.
//!
//! ## The other `SemResolve.h` entries, and where they went
//!
//! `SemResolve.h` declares three more resolver entries, none of which is
//! ported here. Their absence is compile-time loud (there is simply no
//! function to call, and `sema-dump` has no flag that would want one), but
//! the convention in this port is a pointer at the code site — the same one
//! `resolver/mod.rs:1601` and `:1621` use for the S5 items' internals:
//!
//! - **`resolveASTLazy`** (`SemResolve.h:66`) and **`resolveASTInScope`**
//! (`:78`) — lazy compilation and `eval`, i.e. **S5**. They need
//! `SemanticResolver::runLazy`/`runInScope` (SemanticResolver.h:146/158),
//! `FunctionContext`'s lazy constructor, the parent/child `SemContext`
//! tree and its shared binding table — all documented absent at
//! `resolver/mod.rs`'s and `sem_context.rs`'s module docs.
//! - **`resolveCommonJSAST`** (`:86`, plus the inline overload at `:93`) —
//! the `-commonjs` entry, i.e. **S4b**, together with
//! `SemanticResolver::runCommonJSModule` (`SemanticResolver.h:166`) and
//! the three `$SHBuiltin` module branches that panic in
//! `resolver/calls.rs`.
//!
//! `semDump` (`:111`) is the fourth non-resolver entry and IS ported, in
//! [`crate::dump`].
//!
//! Only the untyped arm is ported. The `flowContext` parameter and the
//! `#if HERMES_PARSE_FLOW` block it guards (`FlowChecker::run` + `lowerAST`,
//! cpp:182-192) belong to the FlowChecker component, which this crate does
//! not have; `declCollectorMap` exists in C++ only to hand the resolver's
//! `DeclCollector`s to that checker (`flowContext ? &declCollectorMap :
//! nullptr`), so it is not ported either. The `typed` resolver argument it
//! feeds (`flowContext != nullptr`) is therefore always false.
//!
//! `PerfSection validation("Resolving JavaScript global AST")` (cpp:169) is
//! not ported: there is no `PerfSection` in this tree.
use ;
use Node;
use SourceErrorManager;
use crateSemanticResolver;
use crateSemContext;
/// Resolve the entire AST. Port of `resolveAST` (cpp:163-195), untyped arm.
///
/// \param sem_ctx the result of resolution is stored here.
/// \param root the top-level `Program` node.
/// \param ambient_decls parsed files containing global ambient declarations
/// to insert into the global scope (C++ passes this by reference and the
/// resolver takes its address; an empty slice means "none").
/// \return the resolved (possibly new) root, or `None` on error.
///
/// C++ returns `bool` and resolves in place. This port's resolver is a
/// transforming visitor (see `resolver`'s module doc): rewriting any node
/// rebuilds its ancestors, so the root that comes out is the one carrying
/// the resolution results and is what callers must go on to compile or
/// dump. `None` is C++'s `false`.
/// Perform semantic resolution of the entire AST, without preparing the AST
/// for compilation. Port of `resolveASTForParser` (`SemResolve.cpp:299-310`)
/// — the entry point `hermes-parser-wasm.cpp:104` uses. Unlike [`resolve_ast`]
/// this will not error on features we can parse but not compile, transform
/// the AST, or perform compilation-specific validation (`compile = false`);
/// it also never takes ambient declarations, matching the C++ constructor
/// call `SemanticResolver{astContext, semCtx, /* ambientDecls */ nullptr,
/// /* saveDecls */ nullptr, /* compile */ false}`.
///
/// \param root the top-level `Program` node.
/// \return the (possibly rebuilt) root, ALWAYS — never `None`, unlike
/// [`resolve_ast`]. This is deliberate: `resolveASTForParser`'s only
/// caller, `hermes-parser-wasm.cpp:104`, ignores its `bool` return value
/// and always serializes/dumps whatever `root` ends up holding (checking
/// for errors via a separate diagnostic-handler query, not the return
/// value) — so callers here must do the same: check `sm.error_count()`
/// independently if they need to know whether resolution succeeded. See
/// [`crate::resolver::SemanticResolver::run_always`]'s doc for why this
/// needs a different resolver method than [`resolve_ast`] uses.