@samitouri / QOS-React-2 / commits / 3ce4116930

[rust][sema] Only create one scope per function/class

Fixes up function and class handling to not create nested scopes in some cases. Doesn't affect name resolution otherwise.

Joe Savona committed Aug 17, 2023 at 10:03 UTC 3ce41169303eceb47b4a5147e8fceeea23a145e8
3 files changed +142 -144
compiler/forget/crates/forget_semantic_analysis/src/analyzer.rs
+72 -53
@@ -149,53 +149,49 @@ impl Analyzer {
149 }
150
151 fn visit_function<T: IntoFunction>(&mut self, node: &T) {
152 + assert_eq!(self.manager.scope(self.current).kind, ScopeKind::Function);
153 let function = node.function();
153 - let scope = self.enter(ScopeKind::Function, |visitor| {
154 - for param in &function.params {
155 - // `this` parameters don't declare variables, nor can they have
156 - // default values
157 - if let Pattern::Identifier(param) = param {
158 - if &param.name == "this" {
159 - continue;
160 - }
154 + for param in &function.params {
155 + // `this` parameters don't declare variables, nor can they have
156 + // default values
157 + if let Pattern::Identifier(param) = param {
158 + if &param.name == "this" {
159 + continue;
160 }
162 - Analyzer::visit_declaration_pattern(
163 - visitor,
164 - param,
165 - Some(DeclarationKind::Function),
166 - );
161 }
162 + Analyzer::visit_declaration_pattern(self, param, Some(DeclarationKind::Function));
163 + }
164
169 - if let Some(body) = &function.body {
170 - match body {
171 - FunctionBody::BlockStatement(body) => {
172 - // Skip calling visit_block_statement to avoid creating an extra
173 - // block scope
174 - for item in &body.body {
175 - visitor.visit_statement(item);
176 - }
177 - }
178 - FunctionBody::Expression(body) => {
179 - visitor.visit_expression(body);
165 + if let Some(body) = &function.body {
166 + match body {
167 + FunctionBody::BlockStatement(body) => {
168 + // Skip calling visit_block_statement to avoid creating an extra
169 + // block scope
170 + for item in &body.body {
171 + self.visit_statement(item);
172 }
173 }
174 + FunctionBody::Expression(body) => {
175 + self.visit_expression(body);
176 + }
177 }
183 - });
178 + }
179 self.manager
180 .node_scopes
186 - .insert(AstNode::from(function), scope);
181 + .insert(AstNode::from(function), self.current);
182 }
183
184 fn visit_class<T: IntoClass>(&mut self, node: &T) {
185 + assert_eq!(self.manager.scope(self.current).kind, ScopeKind::Class);
186 let class = node.class();
191 - let scope = self.enter(ScopeKind::Class, |visitor| {
192 - if let Some(super_class) = &class.super_class {
193 - visitor.visit_expression(super_class);
194 - }
187 + if let Some(super_class) = &class.super_class {
188 + self.visit_expression(super_class);
189 + }
190
196 - visitor.visit_class_body(&class.body);
197 - });
198 - self.manager.node_scopes.insert(AstNode::from(class), scope);
191 + self.visit_class_body(&class.body);
192 + self.manager
193 + .node_scopes
194 + .insert(AstNode::from(class), self.current);
195 }
196
197 fn visit_reference_identifier(
@@ -361,7 +357,28 @@ impl Visitor for Analyzer {
357 .node_declarations
358 .insert(AstNode::from(id), declaration);
359 }
364 - Analyzer::visit_class(self, ast);
360 + self.enter(ScopeKind::Class, |visitor| {
361 + Analyzer::visit_class(visitor, ast);
362 + });
363 + }
364 +
365 + fn visit_class_expression(&mut self, ast: &forget_estree::ClassExpression) {
366 + self.enter(ScopeKind::Class, |visitor| {
367 + if let Some(id) = &ast.class.id {
368 + let declaration = visitor.manager.add_declaration(
369 + visitor.current,
370 + id.name.clone(),
371 + DeclarationKind::Function,
372 + id.range,
373 + );
374 + visitor
375 + .manager
376 + .node_declarations
377 + .insert(AstNode::from(id), declaration);
378 + }
379 +
380 + Analyzer::visit_class(visitor, ast);
381 + });
382 }
383
384 fn visit_class_property(&mut self, ast: &forget_estree::ClassProperty) {
@@ -419,32 +436,34 @@ impl Visitor for Analyzer {
436 .node_declarations
437 .insert(AstNode::from(id), declaration);
438 }
422 - Analyzer::visit_function(self, ast);
439 + self.enter(ScopeKind::Function, |visitor| {
440 + Analyzer::visit_function(visitor, ast);
441 + });
442 }
443
444 fn visit_function_expression(&mut self, ast: &forget_estree::FunctionExpression) {
426 - let mut function_scope: Option<ScopeId> = None;
427 - if let Some(id) = &ast.function.id {
428 - function_scope = Some(self.enter_scope(ScopeKind::Function));
429 - let declaration = self.manager.add_declaration(
430 - self.current,
431 - id.name.clone(),
432 - DeclarationKind::Function,
433 - id.range,
434 - );
435 - self.manager
436 - .node_declarations
437 - .insert(AstNode::from(id), declaration);
438 - }
445 + self.enter(ScopeKind::Function, |visitor| {
446 + if let Some(id) = &ast.function.id {
447 + let declaration = visitor.manager.add_declaration(
448 + visitor.current,
449 + id.name.clone(),
450 + DeclarationKind::Function,
451 + id.range,
452 + );
453 + visitor
454 + .manager
455 + .node_declarations
456 + .insert(AstNode::from(id), declaration);
457 + }
458
440 - Analyzer::visit_function(self, ast);
441 - if let Some(function_scope) = function_scope {
442 - self.close_scope(function_scope);
443 - }
459 + Analyzer::visit_function(visitor, ast);
460 + });
461 }
462
463 fn visit_arrow_function_expression(&mut self, ast: &forget_estree::ArrowFunctionExpression) {
447 - Analyzer::visit_function(self, ast);
464 + self.enter(ScopeKind::Function, |visitor| {
465 + Analyzer::visit_function(visitor, ast);
466 + });
467 }
468
469 fn visit_assignment_expression(&mut self, ast: &forget_estree::AssignmentExpression) {
compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@function-hoisting.js.snap
+1 -11
@@ -255,17 +255,7 @@ ScopeManager {
255 },
256 },
257 references: [],
258 - children: [
259 - Scope {
260 - id: ScopeId(
261 - 10,
262 - ),
263 - kind: Function,
264 - declarations: {},
265 - references: [],
266 - children: [],
267 - },
268 - ],
258 + children: [],
259 },
260 ],
261 },
compiler/forget/crates/forget_semantic_analysis/tests/snapshots/analysis_test__fixtures@simple-function.js.snap
+69 -80
@@ -169,91 +169,80 @@ ScopeManager {
169 2,
170 ),
171 },
172 + "c": Declaration {
173 + id: DeclarationId(
174 + 14,
175 + ),
176 + kind: Function,
177 + scope: ScopeId(
178 + 2,
179 + ),
180 + },
181 + "d": Declaration {
182 + id: DeclarationId(
183 + 15,
184 + ),
185 + kind: Let,
186 + scope: ScopeId(
187 + 2,
188 + ),
189 + },
190 },
173 - references: [],
174 - children: [
175 - Scope {
176 - id: ScopeId(
191 + references: [
192 + Reference {
193 + id: ReferenceId(
194 + 1,
195 + ),
196 + kind: Read,
197 + declaration: DeclarationId(
198 + 10,
199 + ),
200 + declaration (name): "a",
201 + scope: ScopeId(
202 + 2,
203 + ),
204 + },
205 + Reference {
206 + id: ReferenceId(
207 + 2,
208 + ),
209 + kind: Read,
210 + declaration: DeclarationId(
211 + 11,
212 + ),
213 + declaration (name): "b",
214 + scope: ScopeId(
215 + 2,
216 + ),
217 + },
218 + Reference {
219 + id: ReferenceId(
220 3,
221 ),
179 - kind: Function,
180 - declarations: {
181 - "c": Declaration {
182 - id: DeclarationId(
183 - 14,
184 - ),
185 - kind: Function,
186 - scope: ScopeId(
187 - 3,
188 - ),
189 - },
190 - "d": Declaration {
191 - id: DeclarationId(
192 - 15,
193 - ),
194 - kind: Let,
195 - scope: ScopeId(
196 - 3,
197 - ),
198 - },
199 - },
200 - references: [
201 - Reference {
202 - id: ReferenceId(
203 - 1,
204 - ),
205 - kind: Read,
206 - declaration: DeclarationId(
207 - 10,
208 - ),
209 - declaration (name): "a",
210 - scope: ScopeId(
211 - 3,
212 - ),
213 - },
214 - Reference {
215 - id: ReferenceId(
216 - 2,
217 - ),
218 - kind: Read,
219 - declaration: DeclarationId(
220 - 11,
221 - ),
222 - declaration (name): "b",
223 - scope: ScopeId(
224 - 3,
225 - ),
226 - },
227 - Reference {
228 - id: ReferenceId(
229 - 3,
230 - ),
231 - kind: Read,
232 - declaration: DeclarationId(
233 - 14,
234 - ),
235 - declaration (name): "c",
236 - scope: ScopeId(
237 - 3,
238 - ),
239 - },
240 - Reference {
241 - id: ReferenceId(
242 - 4,
243 - ),
244 - kind: Read,
245 - declaration: DeclarationId(
246 - 15,
247 - ),
248 - declaration (name): "d",
249 - scope: ScopeId(
250 - 3,
251 - ),
252 - },
253 - ],
254 - children: [],
222 + kind: Read,
223 + declaration: DeclarationId(
224 + 14,
225 + ),
226 + declaration (name): "c",
227 + scope: ScopeId(
228 + 2,
229 + ),
230 + },
231 + Reference {
232 + id: ReferenceId(
233 + 4,
234 + ),
235 + kind: Read,
236 + declaration: DeclarationId(
237 + 15,
238 + ),
239 + declaration (name): "d",
240 + scope: ScopeId(
241 + 2,
242 + ),
243 },
244 ],
245 + children: [],
246 },
247 ],
248 },