[rust][sema] Set root scope kind based on program source type

Rather than always create a Global scope and then immediately add a Module child 
node, we now set the kind of the root scope to global (for scripts) or module 
(for modules) based on the program node.
This commit is contained in:
Joe Savona
2023-08-15 12:24:38 -07:00
parent 875d7175ac
commit 34914796b2
7 changed files with 553 additions and 607 deletions
@@ -2,7 +2,7 @@ use forget_diagnostics::Diagnostic;
use forget_estree::{
AssignmentOperator, AssignmentPropertyOrRestElement, AssignmentTarget, Expression,
ExpressionOrSuper, ForInInit, ForInit, FunctionBody, Identifier, ImportDeclarationSpecifier,
IntoFunction, JSXElementName, Pattern, Program, SourceRange, SourceType, Statement,
IntoFunction, JSXElementName, Pattern, Program, SourceRange, Statement,
VariableDeclarationKind, Visitor,
};
@@ -12,7 +12,7 @@ use crate::{
};
pub fn analyze(ast: &Program) -> ScopeManager {
let mut analyzer = Analyzer::new();
let mut analyzer = Analyzer::new(ast);
analyzer.visit_program(ast);
analyzer.manager
}
@@ -24,8 +24,8 @@ struct Analyzer {
}
impl Analyzer {
fn new() -> Self {
let manager = ScopeManager::new();
fn new(program: &Program) -> Self {
let manager = ScopeManager::new(program.source_type);
let current = manager.root_id();
let labels = Default::default();
Self {
@@ -643,16 +643,8 @@ impl Visitor for Analyzer {
}
fn visit_program(&mut self, ast: &forget_estree::Program) {
if ast.source_type == SourceType::Module {
self.enter(ScopeKind::Module, |visitor| {
for item in &ast.body {
visitor.visit_module_item(item);
}
});
} else {
for item in &ast.body {
self.visit_module_item(item);
}
for item in &ast.body {
self.visit_module_item(item);
}
let scope = self.manager.mut_scope(self.current);
let unresolved = std::mem::take(&mut scope.unresolved);
@@ -1,6 +1,6 @@
use forget_diagnostics::Diagnostic;
use forget_estree::{
BreakStatement, ContinueStatement, ESTreeNode, LabeledStatement, SourceRange,
BreakStatement, ContinueStatement, ESTreeNode, LabeledStatement, SourceRange, SourceType,
VariableDeclarationKind,
};
use forget_utils::PointerAddress;
@@ -33,13 +33,17 @@ impl std::fmt::Debug for ScopeManager {
}
impl ScopeManager {
pub(crate) fn new() -> Self {
pub(crate) fn new(source_type: SourceType) -> Self {
let root_id = ScopeId(0);
let root_kind = match source_type {
SourceType::Module => ScopeKind::Module,
SourceType::Script => ScopeKind::Global,
};
Self {
root: root_id,
scopes: vec![Scope {
id: root_id,
kind: ScopeKind::Global,
kind: root_kind,
parent: None,
declarations: Default::default(),
references: Default::default(),
@@ -33,19 +33,38 @@ Scope {
id: ScopeId(
0,
),
kind: Global,
declarations: {},
kind: Module,
declarations: {
"Component": Declaration {
id: DeclarationId(
0,
),
kind: FunctionDeclaration,
scope: ScopeId(
0,
),
},
},
references: [],
children: [
Scope {
id: ScopeId(
1,
),
kind: Module,
kind: Function,
declarations: {
"Component": Declaration {
"props": Declaration {
id: DeclarationId(
0,
1,
),
kind: FunctionDeclaration,
scope: ScopeId(
1,
),
},
"foo": Declaration {
id: DeclarationId(
2,
),
kind: FunctionDeclaration,
scope: ScopeId(
@@ -53,61 +72,42 @@ Scope {
),
},
},
references: [],
references: [
Reference {
id: ReferenceId(
1,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "foo",
scope: ScopeId(
1,
),
},
Reference {
id: ReferenceId(
2,
),
kind: Read,
declaration: DeclarationId(
1,
),
declaration (name): "props",
scope: ScopeId(
1,
),
},
],
children: [
Scope {
id: ScopeId(
2,
),
kind: Function,
declarations: {
"props": Declaration {
id: DeclarationId(
1,
),
kind: FunctionDeclaration,
scope: ScopeId(
2,
),
},
"foo": Declaration {
id: DeclarationId(
2,
),
kind: FunctionDeclaration,
scope: ScopeId(
2,
),
},
},
references: [
Reference {
id: ReferenceId(
1,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "foo",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
2,
),
kind: Read,
declaration: DeclarationId(
1,
),
declaration (name): "props",
scope: ScopeId(
2,
),
},
],
kind: Block,
declarations: {},
references: [],
children: [
Scope {
id: ScopeId(
@@ -145,43 +145,53 @@ Scope {
id: ScopeId(
7,
),
kind: Block,
kind: Function,
declarations: {},
references: [],
references: [
Reference {
id: ReferenceId(
0,
),
kind: Read,
declaration: DeclarationId(
1,
),
declaration (name): "props",
scope: ScopeId(
7,
),
},
],
children: [
Scope {
id: ScopeId(
8,
),
kind: Function,
declarations: {},
references: [
Reference {
id: ReferenceId(
0,
kind: Block,
declarations: {
"_": Declaration {
id: DeclarationId(
3,
),
kind: Read,
declaration: DeclarationId(
1,
),
declaration (name): "props",
kind: Const,
scope: ScopeId(
8,
),
},
],
},
references: [],
children: [
Scope {
id: ScopeId(
9,
),
kind: Block,
kind: Function,
declarations: {
"_": Declaration {
"bar": Declaration {
id: DeclarationId(
3,
4,
),
kind: Const,
kind: FunctionDeclaration,
scope: ScopeId(
9,
),
@@ -194,29 +204,9 @@ Scope {
10,
),
kind: Function,
declarations: {
"bar": Declaration {
id: DeclarationId(
4,
),
kind: FunctionDeclaration,
scope: ScopeId(
10,
),
},
},
declarations: {},
references: [],
children: [
Scope {
id: ScopeId(
11,
),
kind: Function,
declarations: {},
references: [],
children: [],
},
],
children: [],
},
],
},
@@ -28,225 +28,215 @@ Scope {
id: ScopeId(
0,
),
kind: Global,
declarations: {},
kind: Module,
declarations: {
"Foo": Declaration {
id: DeclarationId(
0,
),
kind: Import,
scope: ScopeId(
0,
),
},
"Bar": Declaration {
id: DeclarationId(
1,
),
kind: Import,
scope: ScopeId(
0,
),
},
"Baz": Declaration {
id: DeclarationId(
2,
),
kind: Import,
scope: ScopeId(
0,
),
},
"Component": Declaration {
id: DeclarationId(
3,
),
kind: FunctionDeclaration,
scope: ScopeId(
0,
),
},
},
references: [],
children: [
Scope {
id: ScopeId(
1,
),
kind: Module,
kind: Function,
declarations: {
"Foo": Declaration {
"props": Declaration {
id: DeclarationId(
0,
),
kind: Import,
scope: ScopeId(
1,
),
},
"Bar": Declaration {
id: DeclarationId(
1,
),
kind: Import,
scope: ScopeId(
1,
),
},
"Baz": Declaration {
id: DeclarationId(
2,
),
kind: Import,
scope: ScopeId(
1,
),
},
"Component": Declaration {
id: DeclarationId(
3,
4,
),
kind: FunctionDeclaration,
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: [],
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: {
"props": Declaration {
id: DeclarationId(
4,
),
kind: FunctionDeclaration,
scope: ScopeId(
2,
),
},
"g": Declaration {
id: DeclarationId(
5,
),
kind: Let,
scope: ScopeId(
2,
),
},
"y": Declaration {
id: DeclarationId(
6,
),
kind: Let,
scope: ScopeId(
2,
),
},
"s": Declaration {
id: DeclarationId(
7,
),
kind: Let,
scope: ScopeId(
2,
),
},
"b": Declaration {
id: DeclarationId(
8,
),
kind: Let,
scope: ScopeId(
2,
),
},
"n": Declaration {
id: DeclarationId(
9,
),
kind: Let,
scope: ScopeId(
2,
),
},
"x": Declaration {
id: DeclarationId(
10,
),
kind: Let,
scope: ScopeId(
2,
),
},
},
references: [
Reference {
id: ReferenceId(
0,
),
kind: Read,
declaration: DeclarationId(
4,
),
declaration (name): "props",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
1,
),
kind: Read,
declaration: DeclarationId(
4,
),
declaration (name): "props",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
2,
),
kind: Read,
declaration: DeclarationId(
4,
),
declaration (name): "props",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
3,
),
kind: Read,
declaration: DeclarationId(
0,
),
declaration (name): "Foo",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
4,
),
kind: Read,
declaration: DeclarationId(
1,
),
declaration (name): "Bar",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
5,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "Baz",
scope: ScopeId(
2,
),
},
],
children: [
Scope {
id: ScopeId(
3,
),
kind: Function,
declarations: {},
references: [],
children: [],
},
Scope {
id: ScopeId(
4,
),
kind: Function,
declarations: {},
references: [],
children: [],
},
],
declarations: {},
references: [],
children: [],
},
Scope {
id: ScopeId(
3,
),
kind: Function,
declarations: {},
references: [],
children: [],
},
],
},
@@ -24,46 +24,70 @@ Scope {
id: ScopeId(
0,
),
kind: Global,
declarations: {},
kind: Module,
declarations: {
"Component": Declaration {
id: DeclarationId(
0,
),
kind: FunctionDeclaration,
scope: ScopeId(
0,
),
},
},
references: [],
children: [
Scope {
id: ScopeId(
1,
),
kind: Module,
kind: Function,
declarations: {
"Component": Declaration {
"props": Declaration {
id: DeclarationId(
0,
1,
),
kind: FunctionDeclaration,
scope: ScopeId(
1,
),
},
"y": Declaration {
id: DeclarationId(
2,
),
kind: Let,
scope: ScopeId(
1,
),
},
},
references: [],
references: [
Reference {
id: ReferenceId(
6,
),
kind: Read,
declaration: DeclarationId(
1,
),
declaration (name): "props",
scope: ScopeId(
1,
),
},
],
children: [
Scope {
id: ScopeId(
2,
),
kind: Function,
kind: For,
declarations: {
"props": Declaration {
"x": Declaration {
id: DeclarationId(
1,
),
kind: FunctionDeclaration,
scope: ScopeId(
2,
),
},
"y": Declaration {
id: DeclarationId(
2,
3,
),
kind: Let,
scope: ScopeId(
@@ -74,13 +98,26 @@ Scope {
references: [
Reference {
id: ReferenceId(
6,
4,
),
kind: Read,
declaration: DeclarationId(
1,
3,
),
declaration (name): "props",
declaration (name): "x",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
5,
),
kind: Read,
declaration: DeclarationId(
3,
),
declaration (name): "x",
scope: ScopeId(
2,
),
@@ -91,22 +128,12 @@ Scope {
id: ScopeId(
3,
),
kind: For,
declarations: {
"x": Declaration {
id: DeclarationId(
3,
),
kind: Let,
scope: ScopeId(
3,
),
},
},
kind: Block,
declarations: {},
references: [
Reference {
id: ReferenceId(
4,
0,
),
kind: Read,
declaration: DeclarationId(
@@ -119,7 +146,20 @@ Scope {
},
Reference {
id: ReferenceId(
5,
1,
),
kind: Write,
declaration: DeclarationId(
2,
),
declaration (name): "y",
scope: ScopeId(
3,
),
},
Reference {
id: ReferenceId(
2,
),
kind: Read,
declaration: DeclarationId(
@@ -130,6 +170,19 @@ Scope {
3,
),
},
Reference {
id: ReferenceId(
3,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "y",
scope: ScopeId(
3,
),
},
],
children: [
Scope {
@@ -138,85 +191,22 @@ Scope {
),
kind: Block,
declarations: {},
references: [
Reference {
id: ReferenceId(
0,
),
kind: Read,
declaration: DeclarationId(
3,
),
declaration (name): "x",
scope: ScopeId(
4,
),
},
Reference {
id: ReferenceId(
1,
),
kind: Write,
declaration: DeclarationId(
2,
),
declaration (name): "y",
scope: ScopeId(
4,
),
},
Reference {
id: ReferenceId(
2,
),
kind: Read,
declaration: DeclarationId(
3,
),
declaration (name): "x",
scope: ScopeId(
4,
),
},
Reference {
id: ReferenceId(
3,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "y",
scope: ScopeId(
4,
),
},
],
children: [
Scope {
id: ScopeId(
5,
),
kind: Block,
declarations: {},
references: [],
children: [],
},
],
references: [],
children: [],
},
],
},
Scope {
id: ScopeId(
6,
),
kind: Block,
declarations: {},
references: [],
children: [],
},
],
},
Scope {
id: ScopeId(
5,
),
kind: Block,
declarations: {},
references: [],
children: [],
},
],
},
],
@@ -19,25 +19,53 @@ Scope {
id: ScopeId(
0,
),
kind: Global,
declarations: {},
kind: Module,
declarations: {
"Component": Declaration {
id: DeclarationId(
0,
),
kind: FunctionDeclaration,
scope: ScopeId(
0,
),
},
},
references: [],
children: [
Scope {
id: ScopeId(
1,
),
kind: Module,
kind: Function,
declarations: {
"Component": Declaration {
"foo": Declaration {
id: DeclarationId(
0,
1,
),
kind: FunctionDeclaration,
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: [
@@ -46,74 +74,36 @@ Scope {
2,
),
kind: Function,
declarations: {
"foo": Declaration {
id: DeclarationId(
declarations: {},
references: [
Reference {
id: ReferenceId(
0,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "a",
scope: ScopeId(
2,
),
},
Reference {
id: ReferenceId(
1,
),
kind: FunctionDeclaration,
scope: ScopeId(
2,
),
},
"a": Declaration {
id: DeclarationId(
2,
),
kind: Let,
scope: ScopeId(
2,
),
},
"b": Declaration {
id: DeclarationId(
kind: Read,
declaration: DeclarationId(
3,
),
kind: Const,
declaration (name): "b",
scope: ScopeId(
2,
),
},
},
references: [],
children: [
Scope {
id: ScopeId(
3,
),
kind: Function,
declarations: {},
references: [
Reference {
id: ReferenceId(
0,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "a",
scope: ScopeId(
3,
),
},
Reference {
id: ReferenceId(
1,
),
kind: Read,
declaration: DeclarationId(
3,
),
declaration (name): "b",
scope: ScopeId(
3,
),
},
],
children: [],
},
],
children: [],
},
],
},
@@ -20,27 +20,69 @@ Scope {
id: ScopeId(
0,
),
kind: Global,
declarations: {},
kind: Module,
declarations: {
"Component": Declaration {
id: DeclarationId(
0,
),
kind: FunctionDeclaration,
scope: ScopeId(
0,
),
},
},
references: [],
children: [
Scope {
id: ScopeId(
1,
),
kind: Module,
kind: Function,
declarations: {
"Component": Declaration {
"a": Declaration {
id: DeclarationId(
0,
1,
),
kind: FunctionDeclaration,
scope: ScopeId(
1,
),
},
"b": Declaration {
id: DeclarationId(
2,
),
kind: Let,
scope: ScopeId(
1,
),
},
"foo": Declaration {
id: DeclarationId(
3,
),
kind: Const,
scope: ScopeId(
1,
),
},
},
references: [],
references: [
Reference {
id: ReferenceId(
4,
),
kind: Read,
declaration: DeclarationId(
3,
),
declaration (name): "foo",
scope: ScopeId(
1,
),
},
],
children: [
Scope {
id: ScopeId(
@@ -48,49 +90,17 @@ Scope {
),
kind: Function,
declarations: {
"a": Declaration {
"foo_": Declaration {
id: DeclarationId(
1,
4,
),
kind: FunctionDeclaration,
scope: ScopeId(
2,
),
},
"b": Declaration {
id: DeclarationId(
2,
),
kind: Let,
scope: ScopeId(
2,
),
},
"foo": Declaration {
id: DeclarationId(
3,
),
kind: Const,
scope: ScopeId(
2,
),
},
},
references: [
Reference {
id: ReferenceId(
4,
),
kind: Read,
declaration: DeclarationId(
3,
),
declaration (name): "foo",
scope: ScopeId(
2,
),
},
],
references: [],
children: [
Scope {
id: ScopeId(
@@ -98,100 +108,80 @@ Scope {
),
kind: Function,
declarations: {
"foo_": Declaration {
"c": Declaration {
id: DeclarationId(
4,
5,
),
kind: FunctionDeclaration,
scope: ScopeId(
3,
),
},
"d": Declaration {
id: DeclarationId(
6,
),
kind: Let,
scope: ScopeId(
3,
),
},
},
references: [],
children: [
Scope {
id: ScopeId(
4,
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,
),
kind: Function,
declarations: {
"c": Declaration {
id: DeclarationId(
5,
),
kind: FunctionDeclaration,
scope: ScopeId(
4,
),
},
"d": Declaration {
id: DeclarationId(
6,
),
kind: Let,
scope: ScopeId(
4,
),
},
},
references: [
Reference {
id: ReferenceId(
0,
),
kind: Read,
declaration: DeclarationId(
1,
),
declaration (name): "a",
scope: ScopeId(
4,
),
},
Reference {
id: ReferenceId(
1,
),
kind: Read,
declaration: DeclarationId(
2,
),
declaration (name): "b",
scope: ScopeId(
4,
),
},
Reference {
id: ReferenceId(
2,
),
kind: Read,
declaration: DeclarationId(
5,
),
declaration (name): "c",
scope: ScopeId(
4,
),
},
Reference {
id: ReferenceId(
3,
),
kind: Read,
declaration: DeclarationId(
6,
),
declaration (name): "d",
scope: ScopeId(
4,
),
},
],
children: [],
},
],
children: [],
},
],
},