diff --git a/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs b/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs index 81ee33d59c..ca2f094282 100644 --- a/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs +++ b/compiler/forget/crates/forget_fixtures/tests/fixtures_test.rs @@ -21,7 +21,7 @@ fn fixtures() { let mut output = String::new(); - let mut analysis = analyze(&ast); + let mut analysis = analyze(&ast, Default::default()); let diagnostics = analysis.diagnostics(); if !diagnostics.is_empty() { for diagnostic in diagnostics { diff --git a/compiler/forget/crates/forget_semantic_analysis/src/analyzer.rs b/compiler/forget/crates/forget_semantic_analysis/src/analyzer.rs index d04989a9e9..c218431af4 100644 --- a/compiler/forget/crates/forget_semantic_analysis/src/analyzer.rs +++ b/compiler/forget/crates/forget_semantic_analysis/src/analyzer.rs @@ -11,12 +11,17 @@ use crate::{ ScopeKind, ScopeManager, }; -pub fn analyze(ast: &Program) -> ScopeManager { - let mut analyzer = Analyzer::new(ast); +pub fn analyze(ast: &Program, options: AnalyzeOptions) -> ScopeManager { + let mut analyzer = Analyzer::new(ast, options); analyzer.visit_program(ast); analyzer.complete() } +#[derive(Debug, Default)] +pub struct AnalyzeOptions { + pub globals: Vec, +} + struct Analyzer { manager: ScopeManager, labels: Vec, @@ -39,8 +44,8 @@ pub struct UnresolvedReference { } impl Analyzer { - fn new(program: &Program) -> Self { - let manager = ScopeManager::new(program.source_type); + fn new(program: &Program, options: AnalyzeOptions) -> Self { + let manager = ScopeManager::new(program.source_type, options.globals); let current = manager.root_id(); let labels = Default::default(); Self { diff --git a/compiler/forget/crates/forget_semantic_analysis/src/lib.rs b/compiler/forget/crates/forget_semantic_analysis/src/lib.rs index 30f0758c19..8cf5c944e8 100644 --- a/compiler/forget/crates/forget_semantic_analysis/src/lib.rs +++ b/compiler/forget/crates/forget_semantic_analysis/src/lib.rs @@ -2,6 +2,6 @@ mod analyzer; mod scope_manager; mod scope_view; -pub use analyzer::analyze; +pub use analyzer::*; pub use scope_manager::*; pub use scope_view::*; diff --git a/compiler/forget/crates/forget_semantic_analysis/src/scope_manager.rs b/compiler/forget/crates/forget_semantic_analysis/src/scope_manager.rs index 8a247e43f6..239cbb880e 100644 --- a/compiler/forget/crates/forget_semantic_analysis/src/scope_manager.rs +++ b/compiler/forget/crates/forget_semantic_analysis/src/scope_manager.rs @@ -7,9 +7,11 @@ use forget_utils::PointerAddress; use indexmap::IndexMap; use crate::scope_view::{DeclarationView, ReferenceView, ScopeView}; +use crate::ScopeManagerView; pub struct ScopeManager { root: ScopeId, + globals: IndexMap, // Storage of the semantic information scopes: Vec, @@ -33,14 +35,15 @@ impl std::fmt::Debug for ScopeManager { } impl ScopeManager { - pub(crate) fn new(source_type: SourceType) -> Self { + pub(crate) fn new(source_type: SourceType, globals: Vec) -> Self { let root_id = ScopeId(0); let root_kind = match source_type { SourceType::Module => ScopeKind::Module, SourceType::Script => ScopeKind::Global, }; - Self { + let mut manager = Self { root: root_id, + globals: IndexMap::with_capacity(globals.len()), scopes: vec![Scope { id: root_id, kind: root_kind, @@ -57,21 +60,33 @@ impl ScopeManager { node_declarations: Default::default(), node_references: Default::default(), diagnostics: Default::default(), + }; + for global in globals { + let id = DeclarationId(manager.declarations.len()); + manager.globals.insert(global.clone(), id); + manager.declarations.push(Declaration { + id, + kind: DeclarationKind::Global, + name: global, + scope: manager.root, + }); } + + manager } - pub fn debug(&self) -> ScopeView<'_> { - let root = self.root(); - ScopeView { - manager: self, - scope: root, - } + pub fn debug(&self) -> ScopeManagerView<'_> { + ScopeManagerView { manager: self } } pub fn diagnostics(&mut self) -> Vec { std::mem::take(&mut self.diagnostics) } + pub fn globals(&self) -> impl Iterator { + self.globals.iter() + } + pub fn root(&self) -> &Scope { &self.scopes[self.root.0] } @@ -198,7 +213,7 @@ impl ScopeManager { return None; } } - return Some(&self.declarations[id.0]); + return Some(declaration); } if let Some(parent) = current.parent { // When leaving a function scope, clear the tdz limit. @@ -210,6 +225,11 @@ impl ScopeManager { } current = &self.scopes[parent.0]; } else { + // Maybe it's a global! + if let Some(id) = self.globals.get(name) { + let declaration = self.declaration(*id); + return Some(declaration); + } return None; } } @@ -322,6 +342,9 @@ impl ScopeManager { .push(Diagnostic::invalid_syntax("Duplicate declaration", range)); } } + DeclarationKind::Global => { + unreachable!("Unexpected explicit declaration of global") + } } // Always create a new declaration and id... @@ -369,6 +392,9 @@ impl ScopeManager { } } } + DeclarationKind::Global => { + unreachable!("Unexpected explicit declaration of global") + } } } @@ -402,7 +428,7 @@ fn is_block_scoped_declaration(kind: DeclarationKind) -> bool { | DeclarationKind::Class | DeclarationKind::Function | DeclarationKind::CatchClause => true, - DeclarationKind::Var => false, + DeclarationKind::Var | DeclarationKind::Global => false, } } @@ -457,6 +483,7 @@ pub struct Label { #[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, Clone)] pub enum DeclarationKind { + Global, Class, Const, Var, diff --git a/compiler/forget/crates/forget_semantic_analysis/src/scope_view.rs b/compiler/forget/crates/forget_semantic_analysis/src/scope_view.rs index af369c5a91..131ea7dc3e 100644 --- a/compiler/forget/crates/forget_semantic_analysis/src/scope_view.rs +++ b/compiler/forget/crates/forget_semantic_analysis/src/scope_view.rs @@ -5,6 +5,32 @@ use crate::{ Scope, ScopeId, ScopeKind, ScopeManager, }; +#[derive(Clone, Copy)] +pub struct ScopeManagerView<'m> { + pub(crate) manager: &'m ScopeManager, +} + +impl<'m> ScopeManagerView<'m> { + pub fn root(&self) -> ScopeView<'m> { + ScopeView { + manager: &self.manager, + scope: self.manager.scope(self.manager.root_id()), + } + } + + pub fn globals(&self) -> impl Iterator { + self.manager.globals() + } +} + +impl<'m> std::fmt::Debug for ScopeManagerView<'m> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ScopeManager") + .field("globals", &self.globals().collect::>()) + .field("root", &self.root()) + .finish() + } +} #[derive(Clone, Copy)] pub struct ScopeView<'m> { pub(crate) manager: &'m ScopeManager, diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/analysis_test.rs b/compiler/forget/crates/forget_semantic_analysis/tests/analysis_test.rs index 7cf869c28d..733ca0817f 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/analysis_test.rs +++ b/compiler/forget/crates/forget_semantic_analysis/tests/analysis_test.rs @@ -1,7 +1,7 @@ use std::fmt::Write; use forget_hermes_parser::parse; -use forget_semantic_analysis::analyze; +use forget_semantic_analysis::{analyze, AnalyzeOptions}; use insta::{assert_snapshot, glob}; use miette::{NamedSource, Report}; @@ -11,7 +11,22 @@ fn fixtures() { println!("fixture {}", path.to_str().unwrap()); let input = std::fs::read_to_string(path).unwrap(); let ast = parse(&input, path.to_str().unwrap()).unwrap(); - let mut analysis = analyze(&ast); + let mut analysis = analyze( + &ast, + AnalyzeOptions { + globals: vec![ + "Array".to_string(), + "Boolean".to_string(), + "console".to_string(), + "global".to_string(), + "Math".to_string(), + "Number".to_string(), + "setInterval".to_string(), + "setTimeout".to_string(), + "String".to_string(), + ], + }, + ); let mut output = String::new(); writeln!(&mut output, "{:#?}", analysis.debug()).unwrap(); diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@block-item-duplication.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@block-item-duplication.js.snap index 0bded5f03c..96c025ae0b 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@block-item-duplication.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@block-item-duplication.js.snap @@ -32,166 +32,224 @@ const x = false; // error Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - "x": Declaration { - id: DeclarationId( - 12, - ), - kind: Const, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "a": Declaration { - id: DeclarationId( - 1, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "b": Declaration { - id: DeclarationId( - 3, - ), - kind: Const, - scope: ScopeId( - 1, - ), - }, - "foo": Declaration { - id: DeclarationId( - 5, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "c": Declaration { - id: DeclarationId( - 10, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Function, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 3, - ), - kind: Function, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 4, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 5, - ), - kind: CatchClause, - declarations: { - "c": Declaration { - id: DeclarationId( - 7, - ), - kind: CatchClause, - scope: ScopeId( - 5, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 6, - ), - kind: Block, - declarations: { - "c": Declaration { - id: DeclarationId( - 8, - ), - kind: Let, - scope: ScopeId( - 6, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 7, - ), - kind: Function, - declarations: {}, - references: [], - children: [], - }, - ], - }, - ], - }, - ], - }, - Scope { - id: ScopeId( + ), + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( 8, ), - kind: Function, - declarations: {}, - references: [], - children: [], - }, + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + "x": Declaration { + id: DeclarationId( + 21, + ), + kind: Const, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "a": Declaration { + id: DeclarationId( + 10, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "b": Declaration { + id: DeclarationId( + 12, + ), + kind: Const, + scope: ScopeId( + 1, + ), + }, + "foo": Declaration { + id: DeclarationId( + 14, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "c": Declaration { + id: DeclarationId( + 19, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Function, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 3, + ), + kind: Function, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 4, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 5, + ), + kind: CatchClause, + declarations: { + "c": Declaration { + id: DeclarationId( + 16, + ), + kind: CatchClause, + scope: ScopeId( + 5, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 6, + ), + kind: Block, + declarations: { + "c": Declaration { + id: DeclarationId( + 17, + ), + kind: Let, + scope: ScopeId( + 6, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 7, + ), + kind: Function, + declarations: {}, + references: [], + children: [], + }, + ], + }, + ], + }, + ], + }, + Scope { + id: ScopeId( + 8, + ), + kind: Function, + declarations: {}, + references: [], + children: [], + }, + ], + }, } Diagnostic( DiagnosticData { diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@function-hoisting.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@function-hoisting.js.snap index d12d7c7b17..36b05b2b08 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@function-hoisting.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@function-hoisting.js.snap @@ -29,204 +29,262 @@ function Component(props) { Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "props": Declaration { - id: DeclarationId( - 1, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "foo": Declaration { - id: DeclarationId( - 2, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 2, - ), - declaration (name): "foo", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 1, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "props", - scope: ScopeId( - 1, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Block, - declarations: {}, - references: [], - children: [ - Scope { - id: ScopeId( - 3, - ), - kind: Block, - declarations: {}, - references: [], - children: [ - Scope { - id: ScopeId( - 4, - ), - kind: Block, - declarations: {}, - references: [], - children: [ - Scope { - id: ScopeId( - 5, - ), - kind: Block, - declarations: {}, - references: [], - children: [ - Scope { - id: ScopeId( - 6, - ), - kind: Block, - declarations: {}, - references: [], - children: [ - Scope { - id: ScopeId( - 7, - ), - kind: Function, - declarations: {}, - references: [ - Reference { - id: ReferenceId( - 2, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "props", - scope: ScopeId( - 7, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 8, - ), - kind: Block, - declarations: { - "_": Declaration { - id: DeclarationId( - 3, - ), - kind: Const, - scope: ScopeId( - 8, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 9, - ), - kind: Function, - declarations: { - "bar": Declaration { - id: DeclarationId( - 4, - ), - kind: Function, - scope: ScopeId( - 9, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 10, - ), - kind: Function, - declarations: {}, - references: [], - children: [], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }, - ], - }, + ), + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "props": Declaration { + id: DeclarationId( + 10, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "foo": Declaration { + id: DeclarationId( + 11, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 11, + ), + declaration (name): "foo", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 1, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "props", + scope: ScopeId( + 1, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Block, + declarations: {}, + references: [], + children: [ + Scope { + id: ScopeId( + 3, + ), + kind: Block, + declarations: {}, + references: [], + children: [ + Scope { + id: ScopeId( + 4, + ), + kind: Block, + declarations: {}, + references: [], + children: [ + Scope { + id: ScopeId( + 5, + ), + kind: Block, + declarations: {}, + references: [], + children: [ + Scope { + id: ScopeId( + 6, + ), + kind: Block, + declarations: {}, + references: [], + children: [ + Scope { + id: ScopeId( + 7, + ), + kind: Function, + declarations: {}, + references: [ + Reference { + id: ReferenceId( + 2, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "props", + scope: ScopeId( + 7, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 8, + ), + kind: Block, + declarations: { + "_": Declaration { + id: DeclarationId( + 12, + ), + kind: Const, + scope: ScopeId( + 8, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 9, + ), + kind: Function, + declarations: { + "bar": Declaration { + id: DeclarationId( + 13, + ), + kind: Function, + scope: ScopeId( + 9, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 10, + ), + kind: Function, + declarations: {}, + references: [], + children: [], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, + ], + }, } Diagnostic( DiagnosticData { diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@globals-and-imports.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@globals-and-imports.js.snap index 2e277c0db7..a96676f242 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@globals-and-imports.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@globals-and-imports.js.snap @@ -24,350 +24,384 @@ function Component(props) { Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Foo": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Import, - scope: ScopeId( - 0, - ), - }, - "Bar": Declaration { - id: DeclarationId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Import, - scope: ScopeId( - 0, - ), - }, - "Baz": Declaration { - id: DeclarationId( + ), + ( + "console", + DeclarationId( 2, ), - kind: Import, - scope: ScopeId( - 0, - ), - }, - "Component": Declaration { - id: DeclarationId( + ), + ( + "global", + DeclarationId( 3, ), - kind: Function, - scope: ScopeId( - 0, + ), + ( + "Math", + DeclarationId( + 4, ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 1, + ), + ( + "Number", + DeclarationId( + 5, ), - kind: Function, - declarations: { - "props": Declaration { - id: DeclarationId( - 4, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "g": Declaration { - id: DeclarationId( - 5, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "y": Declaration { - id: DeclarationId( - 6, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "s": Declaration { - id: DeclarationId( - 7, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "b": Declaration { - id: DeclarationId( - 8, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "n": Declaration { - id: DeclarationId( - 9, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "x": Declaration { - id: DeclarationId( - 10, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 4, - ), - declaration (name): "props", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 1, - ), - kind: Read, - declaration: DeclarationId( - 4, - ), - declaration (name): "props", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 2, - ), - kind: Read, - declaration: DeclarationId( - 4, - ), - declaration (name): "props", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 3, - ), - kind: Read, - declaration: DeclarationId( - 0, - ), - declaration (name): "Foo", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 4, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "Bar", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 5, - ), - kind: Read, - declaration: DeclarationId( - 2, - ), - declaration (name): "Baz", - scope: ScopeId( - 1, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Function, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 3, - ), - kind: Function, - declarations: {}, - references: [], - children: [], - }, - ], - }, + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Foo": Declaration { + id: DeclarationId( + 9, + ), + kind: Import, + scope: ScopeId( + 0, + ), + }, + "Bar": Declaration { + id: DeclarationId( + 10, + ), + kind: Import, + scope: ScopeId( + 0, + ), + }, + "Baz": Declaration { + id: DeclarationId( + 11, + ), + kind: Import, + scope: ScopeId( + 0, + ), + }, + "Component": Declaration { + id: DeclarationId( + 12, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "props": Declaration { + id: DeclarationId( + 13, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "g": Declaration { + id: DeclarationId( + 14, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "y": Declaration { + id: DeclarationId( + 15, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "s": Declaration { + id: DeclarationId( + 16, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "b": Declaration { + id: DeclarationId( + 17, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "n": Declaration { + id: DeclarationId( + 18, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "x": Declaration { + id: DeclarationId( + 19, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 3, + ), + declaration (name): "global", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 1, + ), + kind: Read, + declaration: DeclarationId( + 0, + ), + declaration (name): "Array", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 2, + ), + kind: Read, + declaration: DeclarationId( + 13, + ), + declaration (name): "props", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 3, + ), + kind: Read, + declaration: DeclarationId( + 8, + ), + declaration (name): "String", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 4, + ), + kind: Read, + declaration: DeclarationId( + 1, + ), + declaration (name): "Boolean", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 5, + ), + kind: Read, + declaration: DeclarationId( + 5, + ), + declaration (name): "Number", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 6, + ), + kind: Read, + declaration: DeclarationId( + 4, + ), + declaration (name): "Math", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 7, + ), + kind: Read, + declaration: DeclarationId( + 13, + ), + declaration (name): "props", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 8, + ), + kind: Read, + declaration: DeclarationId( + 13, + ), + declaration (name): "props", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 9, + ), + kind: Read, + declaration: DeclarationId( + 7, + ), + declaration (name): "setTimeout", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 10, + ), + kind: Read, + declaration: DeclarationId( + 6, + ), + declaration (name): "setInterval", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 11, + ), + kind: Read, + declaration: DeclarationId( + 9, + ), + declaration (name): "Foo", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 12, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "Bar", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 13, + ), + kind: Read, + declaration: DeclarationId( + 11, + ), + declaration (name): "Baz", + scope: ScopeId( + 1, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Function, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 3, + ), + kind: Function, + declarations: {}, + references: [], + children: [], + }, + ], + }, + ], + }, } -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 117, - ), - length: 6, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 139, - ), - length: 5, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 169, - ), - length: 6, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 196, - ), - length: 7, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 221, - ), - length: 6, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 242, - ), - length: 4, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 272, - ), - length: 10, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 299, - ), - length: 11, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@labels.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@labels.js.snap index 2beb93388a..4540a61461 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@labels.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@labels.js.snap @@ -20,195 +20,253 @@ function Component(props) { Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "props": Declaration { - id: DeclarationId( - 1, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "y": Declaration { - id: DeclarationId( - 2, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 6, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "props", - scope: ScopeId( - 1, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: For, - declarations: { - "x": Declaration { - id: DeclarationId( - 3, - ), - kind: Let, - scope: ScopeId( - 2, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 3, - ), - declaration (name): "x", - scope: ScopeId( - 2, - ), - }, - Reference { - id: ReferenceId( - 1, - ), - kind: Read, - declaration: DeclarationId( - 3, - ), - declaration (name): "x", - scope: ScopeId( - 2, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 3, - ), - kind: Block, - declarations: {}, - references: [ - Reference { - id: ReferenceId( - 2, - ), - kind: Read, - declaration: DeclarationId( - 3, - ), - declaration (name): "x", - scope: ScopeId( - 3, - ), - }, - Reference { - id: ReferenceId( - 3, - ), - kind: Write, - declaration: DeclarationId( - 2, - ), - declaration (name): "y", - scope: ScopeId( - 3, - ), - }, - Reference { - id: ReferenceId( - 4, - ), - kind: Read, - declaration: DeclarationId( - 3, - ), - declaration (name): "x", - scope: ScopeId( - 3, - ), - }, - Reference { - id: ReferenceId( - 5, - ), - kind: Read, - declaration: DeclarationId( - 2, - ), - declaration (name): "y", - scope: ScopeId( - 3, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 4, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - ], - }, - ], - }, - Scope { - id: ScopeId( - 5, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - ], - }, + ), + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "props": Declaration { + id: DeclarationId( + 10, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "y": Declaration { + id: DeclarationId( + 11, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 6, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "props", + scope: ScopeId( + 1, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: For, + declarations: { + "x": Declaration { + id: DeclarationId( + 12, + ), + kind: Let, + scope: ScopeId( + 2, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 12, + ), + declaration (name): "x", + scope: ScopeId( + 2, + ), + }, + Reference { + id: ReferenceId( + 1, + ), + kind: Read, + declaration: DeclarationId( + 12, + ), + declaration (name): "x", + scope: ScopeId( + 2, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 3, + ), + kind: Block, + declarations: {}, + references: [ + Reference { + id: ReferenceId( + 2, + ), + kind: Read, + declaration: DeclarationId( + 12, + ), + declaration (name): "x", + scope: ScopeId( + 3, + ), + }, + Reference { + id: ReferenceId( + 3, + ), + kind: Write, + declaration: DeclarationId( + 11, + ), + declaration (name): "y", + scope: ScopeId( + 3, + ), + }, + Reference { + id: ReferenceId( + 4, + ), + kind: Read, + declaration: DeclarationId( + 12, + ), + declaration (name): "x", + scope: ScopeId( + 3, + ), + }, + Reference { + id: ReferenceId( + 5, + ), + kind: Read, + declaration: DeclarationId( + 11, + ), + declaration (name): "y", + scope: ScopeId( + 3, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 4, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + ], + }, + ], + }, + Scope { + id: ScopeId( + 5, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + ], + }, + ], + }, } diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@let-const-hoisting.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@let-const-hoisting.js.snap index a7665a2a87..97a36657f4 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@let-const-hoisting.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@let-const-hoisting.js.snap @@ -15,98 +15,156 @@ function Component() { Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "foo": Declaration { - id: DeclarationId( - 1, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "a": Declaration { - id: DeclarationId( - 2, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "b": Declaration { - id: DeclarationId( - 3, - ), - kind: Const, - scope: ScopeId( - 1, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Function, - declarations: {}, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 2, - ), - declaration (name): "a", - scope: ScopeId( - 2, - ), - }, - Reference { - id: ReferenceId( - 1, - ), - kind: Read, - declaration: DeclarationId( - 3, - ), - declaration (name): "b", - scope: ScopeId( - 2, - ), - }, - ], - children: [], - }, - ], - }, + ), + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "foo": Declaration { + id: DeclarationId( + 10, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "a": Declaration { + id: DeclarationId( + 11, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "b": Declaration { + id: DeclarationId( + 12, + ), + kind: Const, + scope: ScopeId( + 1, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Function, + declarations: {}, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 11, + ), + declaration (name): "a", + scope: ScopeId( + 2, + ), + }, + Reference { + id: ReferenceId( + 1, + ), + kind: Read, + declaration: DeclarationId( + 12, + ), + declaration (name): "b", + scope: ScopeId( + 2, + ), + }, + ], + children: [], + }, + ], + }, + ], + }, } diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@simple-function.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@simple-function.js.snap index 60c13dff4a..ffefd1f4e6 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@simple-function.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@simple-function.js.snap @@ -16,193 +16,248 @@ function Component(a) { Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "a": Declaration { - id: DeclarationId( - 1, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "b": Declaration { - id: DeclarationId( - 2, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "foo": Declaration { - id: DeclarationId( - 3, - ), - kind: Const, - scope: ScopeId( - 1, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 4, - ), - kind: Read, - declaration: DeclarationId( - 3, - ), - declaration (name): "foo", - scope: ScopeId( - 1, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Function, - declarations: { - "foo_": Declaration { - id: DeclarationId( - 4, - ), - kind: Function, - scope: ScopeId( - 2, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( - 3, - ), - kind: Function, - declarations: { - "c": Declaration { - id: DeclarationId( - 5, - ), - kind: Function, - scope: ScopeId( - 3, - ), - }, - "d": Declaration { - id: DeclarationId( - 6, - ), - kind: Let, - scope: ScopeId( - 3, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "a", - scope: ScopeId( - 3, - ), - }, - Reference { - id: ReferenceId( - 1, - ), - kind: Read, - declaration: DeclarationId( - 2, - ), - declaration (name): "b", - scope: ScopeId( - 3, - ), - }, - Reference { - id: ReferenceId( - 2, - ), - kind: Read, - declaration: DeclarationId( - 5, - ), - declaration (name): "c", - scope: ScopeId( - 3, - ), - }, - Reference { - id: ReferenceId( - 3, - ), - kind: Read, - declaration: DeclarationId( - 6, - ), - declaration (name): "d", - scope: ScopeId( - 3, - ), - }, - ], - children: [], - }, - ], - }, - ], - }, - ], -} -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 26, - ), - length: 4, - }, ), - related_information: [], - severity: InvalidSyntax, - data: [], + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), + ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "a": Declaration { + id: DeclarationId( + 10, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "b": Declaration { + id: DeclarationId( + 11, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "foo": Declaration { + id: DeclarationId( + 12, + ), + kind: Const, + scope: ScopeId( + 1, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 4, + ), + declaration (name): "Math", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 5, + ), + kind: Read, + declaration: DeclarationId( + 12, + ), + declaration (name): "foo", + scope: ScopeId( + 1, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Function, + declarations: { + "foo_": Declaration { + id: DeclarationId( + 13, + ), + kind: Function, + scope: ScopeId( + 2, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 3, + ), + kind: Function, + declarations: { + "c": Declaration { + id: DeclarationId( + 14, + ), + kind: Function, + scope: ScopeId( + 3, + ), + }, + "d": Declaration { + id: DeclarationId( + 15, + ), + kind: Let, + scope: ScopeId( + 3, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 1, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "a", + scope: ScopeId( + 3, + ), + }, + Reference { + id: ReferenceId( + 2, + ), + kind: Read, + declaration: DeclarationId( + 11, + ), + declaration (name): "b", + scope: ScopeId( + 3, + ), + }, + Reference { + id: ReferenceId( + 3, + ), + kind: Read, + declaration: DeclarationId( + 14, + ), + declaration (name): "c", + scope: ScopeId( + 3, + ), + }, + Reference { + id: ReferenceId( + 4, + ), + kind: Read, + declaration: DeclarationId( + 15, + ), + declaration (name): "d", + scope: ScopeId( + 3, + ), + }, + ], + children: [], + }, + ], + }, + ], + }, + ], }, -) +} diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@tdz.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@tdz.js.snap index 3668fed4ab..d6d72f66e4 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@tdz.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@tdz.js.snap @@ -21,109 +21,167 @@ function Component() { Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "foo": Declaration { - id: DeclarationId( - 1, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "a": Declaration { - id: DeclarationId( - 2, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 1, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "foo", - scope: ScopeId( - 1, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 3, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 4, - ), - kind: Function, - declarations: {}, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 2, - ), - declaration (name): "a", - scope: ScopeId( - 4, - ), - }, - ], - children: [], - }, - ], - }, + ), + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "foo": Declaration { + id: DeclarationId( + 10, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "a": Declaration { + id: DeclarationId( + 11, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 1, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "foo", + scope: ScopeId( + 1, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 3, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 4, + ), + kind: Function, + declarations: {}, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 11, + ), + declaration (name): "a", + scope: ScopeId( + 4, + ), + }, + ], + children: [], + }, + ], + }, + ], + }, } Diagnostic( DiagnosticData { diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-duplication.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-duplication.js.snap index 40e3cf90e1..63403030e2 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-duplication.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-duplication.js.snap @@ -36,177 +36,274 @@ function Component() { Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "a": Declaration { - id: DeclarationId( - 1, - ), - kind: Let, - scope: ScopeId( - 1, - ), - }, - "b": Declaration { - id: DeclarationId( - 3, - ), - kind: Const, - scope: ScopeId( - 1, - ), - }, - "c": Declaration { - id: DeclarationId( - 6, - ), - kind: Var, - scope: ScopeId( - 1, - ), - }, - "d": Declaration { - id: DeclarationId( - 8, - ), - kind: Var, - scope: ScopeId( - 1, - ), - }, - "e": Declaration { - id: DeclarationId( - 9, - ), - kind: Var, - scope: ScopeId( - 1, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 9, - ), - declaration (name): "e", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 1, - ), - kind: Read, - declaration: DeclarationId( - 9, - ), - declaration (name): "e", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 2, - ), - kind: Read, - declaration: DeclarationId( - 9, - ), - declaration (name): "e", - scope: ScopeId( - 1, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 3, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 4, - ), - kind: Block, - declarations: { - "c": Declaration { - id: DeclarationId( - 5, - ), - kind: Let, - scope: ScopeId( - 4, - ), - }, - }, - references: [], - children: [], - }, - Scope { - id: ScopeId( - 5, - ), - kind: Block, - declarations: { - "d": Declaration { - id: DeclarationId( - 7, - ), - kind: Const, - scope: ScopeId( - 5, - ), - }, - }, - references: [], - children: [], - }, - ], - }, + ), + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "a": Declaration { + id: DeclarationId( + 10, + ), + kind: Let, + scope: ScopeId( + 1, + ), + }, + "b": Declaration { + id: DeclarationId( + 12, + ), + kind: Const, + scope: ScopeId( + 1, + ), + }, + "c": Declaration { + id: DeclarationId( + 15, + ), + kind: Var, + scope: ScopeId( + 1, + ), + }, + "d": Declaration { + id: DeclarationId( + 17, + ), + kind: Var, + scope: ScopeId( + 1, + ), + }, + "e": Declaration { + id: DeclarationId( + 18, + ), + kind: Var, + scope: ScopeId( + 1, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 2, + ), + declaration (name): "console", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 1, + ), + kind: Read, + declaration: DeclarationId( + 18, + ), + declaration (name): "e", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 2, + ), + kind: Read, + declaration: DeclarationId( + 2, + ), + declaration (name): "console", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 3, + ), + kind: Read, + declaration: DeclarationId( + 18, + ), + declaration (name): "e", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 4, + ), + kind: Read, + declaration: DeclarationId( + 2, + ), + declaration (name): "console", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 5, + ), + kind: Read, + declaration: DeclarationId( + 18, + ), + declaration (name): "e", + scope: ScopeId( + 1, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 3, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 4, + ), + kind: Block, + declarations: { + "c": Declaration { + id: DeclarationId( + 14, + ), + kind: Let, + scope: ScopeId( + 4, + ), + }, + }, + references: [], + children: [], + }, + Scope { + id: ScopeId( + 5, + ), + kind: Block, + declarations: { + "d": Declaration { + id: DeclarationId( + 16, + ), + kind: Const, + scope: ScopeId( + 5, + ), + }, + }, + references: [], + children: [], + }, + ], + }, + ], + }, } Diagnostic( DiagnosticData { @@ -272,52 +369,4 @@ Diagnostic( data: [], }, ) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 305, - ), - length: 7, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 341, - ), - length: 7, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) -Diagnostic( - DiagnosticData { - message: "Undefined variable", - span: Some( - SourceSpan { - offset: SourceOffset( - 373, - ), - length: 7, - }, - ), - related_information: [], - severity: InvalidSyntax, - data: [], - }, -) diff --git a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-hoisting.js.snap b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-hoisting.js.snap index ccb9f084e7..01ef564255 100644 --- a/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-hoisting.js.snap +++ b/compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@var-hoisting.js.snap @@ -26,215 +26,273 @@ var baz; Analysis: -Scope { - id: ScopeId( - 0, - ), - kind: Module, - declarations: { - "Component": Declaration { - id: DeclarationId( +ScopeManager { + globals: [ + ( + "Array", + DeclarationId( 0, ), - kind: Function, - scope: ScopeId( - 0, - ), - }, - "baz": Declaration { - id: DeclarationId( - 5, - ), - kind: Var, - scope: ScopeId( - 0, - ), - }, - }, - references: [], - children: [ - Scope { - id: ScopeId( + ), + ( + "Boolean", + DeclarationId( 1, ), - kind: Function, - declarations: { - "props": Declaration { - id: DeclarationId( - 1, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "foo": Declaration { - id: DeclarationId( - 2, - ), - kind: Function, - scope: ScopeId( - 1, - ), - }, - "bar": Declaration { - id: DeclarationId( - 4, - ), - kind: Var, - scope: ScopeId( - 1, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 0, - ), - kind: Read, - declaration: DeclarationId( - 4, - ), - declaration (name): "bar", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 1, - ), - kind: Write, - declaration: DeclarationId( - 4, - ), - declaration (name): "bar", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 2, - ), - kind: Read, - declaration: DeclarationId( - 5, - ), - declaration (name): "baz", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 3, - ), - kind: Write, - declaration: DeclarationId( - 5, - ), - declaration (name): "baz", - scope: ScopeId( - 1, - ), - }, - Reference { - id: ReferenceId( - 7, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "props", - scope: ScopeId( - 1, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 2, - ), - kind: Function, - declarations: { - "bar": Declaration { - id: DeclarationId( - 3, - ), - kind: Var, - scope: ScopeId( - 2, - ), - }, - }, - references: [ - Reference { - id: ReferenceId( - 4, - ), - kind: Read, - declaration: DeclarationId( - 3, - ), - declaration (name): "bar", - scope: ScopeId( - 2, - ), - }, - Reference { - id: ReferenceId( - 5, - ), - kind: Write, - declaration: DeclarationId( - 3, - ), - declaration (name): "bar", - scope: ScopeId( - 2, - ), - }, - Reference { - id: ReferenceId( - 6, - ), - kind: Read, - declaration: DeclarationId( - 1, - ), - declaration (name): "props", - scope: ScopeId( - 2, - ), - }, - ], - children: [ - Scope { - id: ScopeId( - 3, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - ], - }, - Scope { - id: ScopeId( - 4, - ), - kind: Block, - declarations: {}, - references: [], - children: [], - }, - ], - }, + ), + ( + "console", + DeclarationId( + 2, + ), + ), + ( + "global", + DeclarationId( + 3, + ), + ), + ( + "Math", + DeclarationId( + 4, + ), + ), + ( + "Number", + DeclarationId( + 5, + ), + ), + ( + "setInterval", + DeclarationId( + 6, + ), + ), + ( + "setTimeout", + DeclarationId( + 7, + ), + ), + ( + "String", + DeclarationId( + 8, + ), + ), ], + root: Scope { + id: ScopeId( + 0, + ), + kind: Module, + declarations: { + "Component": Declaration { + id: DeclarationId( + 9, + ), + kind: Function, + scope: ScopeId( + 0, + ), + }, + "baz": Declaration { + id: DeclarationId( + 14, + ), + kind: Var, + scope: ScopeId( + 0, + ), + }, + }, + references: [], + children: [ + Scope { + id: ScopeId( + 1, + ), + kind: Function, + declarations: { + "props": Declaration { + id: DeclarationId( + 10, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "foo": Declaration { + id: DeclarationId( + 11, + ), + kind: Function, + scope: ScopeId( + 1, + ), + }, + "bar": Declaration { + id: DeclarationId( + 13, + ), + kind: Var, + scope: ScopeId( + 1, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 0, + ), + kind: Read, + declaration: DeclarationId( + 13, + ), + declaration (name): "bar", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 1, + ), + kind: Write, + declaration: DeclarationId( + 13, + ), + declaration (name): "bar", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 2, + ), + kind: Read, + declaration: DeclarationId( + 14, + ), + declaration (name): "baz", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 3, + ), + kind: Write, + declaration: DeclarationId( + 14, + ), + declaration (name): "baz", + scope: ScopeId( + 1, + ), + }, + Reference { + id: ReferenceId( + 7, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "props", + scope: ScopeId( + 1, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 2, + ), + kind: Function, + declarations: { + "bar": Declaration { + id: DeclarationId( + 12, + ), + kind: Var, + scope: ScopeId( + 2, + ), + }, + }, + references: [ + Reference { + id: ReferenceId( + 4, + ), + kind: Read, + declaration: DeclarationId( + 12, + ), + declaration (name): "bar", + scope: ScopeId( + 2, + ), + }, + Reference { + id: ReferenceId( + 5, + ), + kind: Write, + declaration: DeclarationId( + 12, + ), + declaration (name): "bar", + scope: ScopeId( + 2, + ), + }, + Reference { + id: ReferenceId( + 6, + ), + kind: Read, + declaration: DeclarationId( + 10, + ), + declaration (name): "props", + scope: ScopeId( + 2, + ), + }, + ], + children: [ + Scope { + id: ScopeId( + 3, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + ], + }, + Scope { + id: ScopeId( + 4, + ), + kind: Block, + declarations: {}, + references: [], + children: [], + }, + ], + }, + ], + }, }