Skip to content

Commit

Permalink
fix(semantic): do not create a global symbol for declare global {}
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Sep 24, 2024
1 parent 09a24cd commit 5b8ff48
Show file tree
Hide file tree
Showing 9 changed files with 70 additions and 59 deletions.
3 changes: 3 additions & 0 deletions crates/oxc_ast/src/ast/ts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,9 @@ pub enum TSTypePredicateName<'a> {
pub struct TSModuleDeclaration<'a> {
#[serde(flatten)]
pub span: Span,
/// The name of the module/namespace being declared.
///
/// Note that for `declare global {}`, no symbol will be created for the module name.
pub id: TSModuleDeclarationName<'a>,
#[scope(enter_before)]
pub body: Option<TSModuleDeclarationBody<'a>>,
Expand Down
8 changes: 4 additions & 4 deletions crates/oxc_ast/src/generated/ast_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4417,7 +4417,7 @@ impl<'a> AstBuilder<'a> {
///
/// ## Parameters
/// - span: The [`Span`] covering this node
/// - id
/// - id: The name of the module/namespace being declared.
/// - body
/// - kind: The keyword used to define this module declaration.
/// - declare
Expand Down Expand Up @@ -11381,7 +11381,7 @@ impl<'a> AstBuilder<'a> {
///
/// ## Parameters
/// - span: The [`Span`] covering this node
/// - id
/// - id: The name of the module/namespace being declared.
/// - body
/// - kind: The keyword used to define this module declaration.
/// - declare
Expand All @@ -11403,7 +11403,7 @@ impl<'a> AstBuilder<'a> {
///
/// ## Parameters
/// - span: The [`Span`] covering this node
/// - id
/// - id: The name of the module/namespace being declared.
/// - body
/// - kind: The keyword used to define this module declaration.
/// - declare
Expand Down Expand Up @@ -11483,7 +11483,7 @@ impl<'a> AstBuilder<'a> {
///
/// ## Parameters
/// - span: The [`Span`] covering this node
/// - id
/// - id: The name of the module/namespace being declared.
/// - body
/// - kind: The keyword used to define this module declaration.
/// - declare
Expand Down
8 changes: 7 additions & 1 deletion crates/oxc_semantic/src/binder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,10 +411,16 @@ impl<'a> Binder<'a> for TSEnumMember<'a> {

impl<'a> Binder<'a> for TSModuleDeclaration<'a> {
fn bind(&self, builder: &mut SemanticBuilder) {
// do not bind `global` for `declare global { ... }`
if matches!(self.kind, TSModuleDeclarationKind::Global) {
return;
}

// At declaration time a module has no value declaration it is only when a value declaration
// is made inside a the scope of a module that the symbol is modified
let ambient = if self.declare { SymbolFlags::Ambient } else { SymbolFlags::None };
builder.declare_symbol(
// FIXME: insert symbol_id into TSModuleDeclarationName AST node
let _symbol_id = builder.declare_symbol(
self.id.span(),
self.id.name().as_str(),
SymbolFlags::NameSpaceModule | ambient,
Expand Down
15 changes: 10 additions & 5 deletions crates/oxc_semantic/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ pub struct SemanticBuilder<'a> {
// we need the to know the modules we are inside
// and when we reach a value declaration we set it
// to value like
pub(crate) namespace_stack: Vec<SymbolId>,
pub(crate) namespace_stack: Vec<Option<SymbolId>>,
current_reference_flags: ReferenceFlags,
pub(crate) hoisting_variables: FxHashMap<ScopeId, FxHashMap<Atom<'a>, SymbolId>>,

Expand Down Expand Up @@ -1847,8 +1847,9 @@ impl<'a> SemanticBuilder<'a> {
let symbol_id = self
.scope
.get_bindings(self.current_scope_id)
.get(module_declaration.id.name().as_str());
self.namespace_stack.push(*symbol_id.unwrap());
.get(module_declaration.id.name().as_str())
.copied();
self.namespace_stack.push(symbol_id);
self.current_symbol_flags -= SymbolFlags::Export;
}
AstKind::TSTypeAliasDeclaration(type_alias_declaration) => {
Expand Down Expand Up @@ -2025,11 +2026,15 @@ impl<'a> SemanticBuilder<'a> {

fn make_all_namespaces_valuelike(&mut self) {
for symbol_id in &self.namespace_stack {
let Some(symbol_id) = *symbol_id else {
continue;
};

// Ambient modules cannot be value modules
if self.symbols.get_flags(*symbol_id).intersects(SymbolFlags::Ambient) {
if self.symbols.get_flags(symbol_id).intersects(SymbolFlags::Ambient) {
continue;
}
self.symbols.union_flag(*symbol_id, SymbolFlags::ValueModule);
self.symbols.union_flag(symbol_id, SymbolFlags::ValueModule);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@ input_file: crates/oxc_semantic/tests/fixtures/typescript-eslint/ts-module/globa
"flags": "ScopeFlags(StrictMode | Top)",
"id": 0,
"node": "Program",
"symbols": [
{
"flags": "SymbolFlags(NameSpaceModule | Ambient)",
"id": 0,
"name": "global",
"node": "TSModuleDeclaration(global)",
"references": []
}
]
"symbols": []
}
]
26 changes: 26 additions & 0 deletions crates/oxc_semantic/tests/integration/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -449,3 +449,29 @@ fn test_tagged_templates() {
.has_number_of_writes(0)
.test();
}

#[test]
fn test_module_like_declarations() {
SemanticTester::ts("namespace A { export const x = 1; }")
.has_root_symbol("A")
.contains_flags(SymbolFlags::NameSpaceModule)
.test();

SemanticTester::ts("module A { export const x = 1; }")
.has_root_symbol("A")
.contains_flags(SymbolFlags::NameSpaceModule)
.test();

SemanticTester::ts(r#"module "A" { export const x = 1; }"#)
.has_root_symbol("A")
.contains_flags(SymbolFlags::NameSpaceModule)
.test();

let test = SemanticTester::ts("declare global { interface Window { x: number; } }");
let semantic = test.build();
let global = semantic.symbols().names.iter().find(|name| *name == "global");
assert!(
global.is_none(),
"A symbol should not be created for global augmentation declarations."
);
}
2 changes: 1 addition & 1 deletion tasks/coverage/snapshots/semantic_babel.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1340,7 +1340,7 @@ rebuilt : ScopeId(0): []

tasks/coverage/babel/packages/babel-parser/test/fixtures/typescript/module-namespace/head-declare/input.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["M", "N", "global", "m"]
after transform: ScopeId(0): ["M", "N", "m"]
rebuilt : ScopeId(0): []
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(3), ScopeId(4), ScopeId(5)]
Expand Down
49 changes: 14 additions & 35 deletions tasks/coverage/snapshots/semantic_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -9009,10 +9009,7 @@ after transform: ScopeId(1): ["E", "i"]
rebuilt : ScopeId(1): ["i"]

tasks/coverage/typescript/tests/cases/compiler/declarationEmitRetainsJsdocyComments.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["Foo", "foo", "global", "someMethod"]
rebuilt : ScopeId(0): ["Foo", "foo", "someMethod"]
Scope children mismatch:
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(4), ScopeId(6)]
rebuilt : ScopeId(0): [ScopeId(1), ScopeId(4)]

Expand Down Expand Up @@ -10734,7 +10731,7 @@ rebuilt : []

tasks/coverage/typescript/tests/cases/compiler/doubleUnderscoreReactNamespace.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["__foot", "_jsxFileName", "global", "thing"]
after transform: ScopeId(0): ["__foot", "_jsxFileName", "thing"]
rebuilt : ScopeId(0): ["_jsxFileName", "thing"]
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
Expand Down Expand Up @@ -17286,10 +17283,7 @@ after transform: ReferenceId(2): Some("M")
rebuilt : ReferenceId(6): Some("M")

tasks/coverage/typescript/tests/cases/compiler/globalFunctionAugmentationOverload.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["global"]
rebuilt : ScopeId(0): []
Scope children mismatch:
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
rebuilt : ScopeId(0): []

Expand Down Expand Up @@ -21003,7 +20997,7 @@ rebuilt : ScopeId(0): [ScopeId(1)]

tasks/coverage/typescript/tests/cases/compiler/jsxCallbackWithDestructuring.tsx
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["Component", "MyComponent", "RouteProps", "_jsx", "_jsxFileName", "global"]
after transform: ScopeId(0): ["Component", "MyComponent", "RouteProps", "_jsx", "_jsxFileName"]
rebuilt : ScopeId(0): ["MyComponent", "_jsx", "_jsxFileName"]
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(2), ScopeId(5), ScopeId(14), ScopeId(15), ScopeId(16)]
Expand Down Expand Up @@ -23043,33 +23037,30 @@ rebuilt : ScopeId(0): [ScopeId(1)]

tasks/coverage/typescript/tests/cases/compiler/moduleAugmentationGlobal1.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["A", "global", "x", "y"]
after transform: ScopeId(0): ["A", "x", "y"]
rebuilt : ScopeId(0): ["x", "y"]
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
rebuilt : ScopeId(0): []

tasks/coverage/typescript/tests/cases/compiler/moduleAugmentationGlobal2.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["A", "global", "x", "y"]
after transform: ScopeId(0): ["A", "x", "y"]
rebuilt : ScopeId(0): ["x", "y"]
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
rebuilt : ScopeId(0): []

tasks/coverage/typescript/tests/cases/compiler/moduleAugmentationGlobal3.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["A", "global"]
after transform: ScopeId(0): ["A"]
rebuilt : ScopeId(0): []
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
rebuilt : ScopeId(0): []

tasks/coverage/typescript/tests/cases/compiler/moduleAugmentationGlobal4.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["global"]
rebuilt : ScopeId(0): []
Scope children mismatch:
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
rebuilt : ScopeId(0): []

Expand Down Expand Up @@ -37199,10 +37190,7 @@ after transform: [ReferenceId(7), ReferenceId(9), ReferenceId(13)]
rebuilt : [ReferenceId(4)]

tasks/coverage/typescript/tests/cases/compiler/uniqueSymbolAssignmentOnGlobalAugmentationSuceeds.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["FOO_SYMBOL", "foo", "global"]
rebuilt : ScopeId(0): ["FOO_SYMBOL", "foo"]
Scope children mismatch:
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(3)]
rebuilt : ScopeId(0): [ScopeId(1)]
Bindings mismatch:
Expand Down Expand Up @@ -40502,14 +40490,11 @@ after transform: [ReferenceId(0), ReferenceId(11)]
rebuilt : [ReferenceId(10)]

tasks/coverage/typescript/tests/cases/conformance/controlFlow/controlFlowInstanceofExtendsFunction.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["X", "Y", "global", "x"]
rebuilt : ScopeId(0): ["X", "Y", "x"]
Scope children mismatch:
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(4), ScopeId(5), ScopeId(8), ScopeId(9)]
rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2), ScopeId(5), ScopeId(6)]
Symbol reference IDs mismatch:
after transform: SymbolId(2): [ReferenceId(2), ReferenceId(5), ReferenceId(7), ReferenceId(9)]
after transform: SymbolId(1): [ReferenceId(2), ReferenceId(5), ReferenceId(7), ReferenceId(9)]
rebuilt : SymbolId(0): [ReferenceId(2), ReferenceId(6), ReferenceId(8)]

tasks/coverage/typescript/tests/cases/conformance/controlFlow/controlFlowOptionalChain2.ts
Expand Down Expand Up @@ -42020,10 +42005,7 @@ semantic error: The only valid meta property for import is import.meta
The only valid meta property for import is import.meta

tasks/coverage/typescript/tests/cases/conformance/es2019/importMeta/importMetaNarrowing.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["global"]
rebuilt : ScopeId(0): []
Scope children mismatch:
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(3)]
rebuilt : ScopeId(0): [ScopeId(1)]

Expand Down Expand Up @@ -42503,7 +42485,7 @@ rebuilt : []

tasks/coverage/typescript/tests/cases/conformance/es6/Symbols/symbolProperty61.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["InteropObservable", "MyObservable", "from", "global", "observable"]
after transform: ScopeId(0): ["InteropObservable", "MyObservable", "from", "observable"]
rebuilt : ScopeId(0): ["MyObservable", "from", "observable"]
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(3), ScopeId(7), ScopeId(9)]
Expand Down Expand Up @@ -47533,10 +47515,7 @@ after transform: SymbolId(0): [ReferenceId(0), ReferenceId(1), ReferenceId(2)]
rebuilt : SymbolId(0): [ReferenceId(0)]

tasks/coverage/typescript/tests/cases/conformance/externalModules/globalAugmentationModuleResolution.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["global"]
rebuilt : ScopeId(0): []
Scope children mismatch:
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1)]
rebuilt : ScopeId(0): []

Expand Down
8 changes: 4 additions & 4 deletions tasks/transform_conformance/snapshots/babel.snap.md
Original file line number Diff line number Diff line change
Expand Up @@ -2701,14 +2701,14 @@ Missing SymbolId: X
Missing SymbolId: _X
Missing ReferenceId: X
Missing ReferenceId: X
Bindings mismatch:
after transform: ScopeId(0): ["X", "global", "i18n"]
rebuilt : ScopeId(0): ["X", "i18n"]
Binding symbols mismatch:
after transform: ScopeId(0): [SymbolId(2), SymbolId(4)]
rebuilt : ScopeId(0): [SymbolId(0), SymbolId(3)]
Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(3), ScopeId(4)]
rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2)]
Binding symbols mismatch:
after transform: ScopeId(3): [SymbolId(4), SymbolId(6)]
after transform: ScopeId(3): [SymbolId(3), SymbolId(5)]
rebuilt : ScopeId(1): [SymbolId(1), SymbolId(2)]

* namespace/empty-removed/input.ts
Expand Down

0 comments on commit 5b8ff48

Please sign in to comment.