[rust][sema] Comments
Joe Savona committed
Aug 4, 2023 at 12:16 UTC
ab5213e8f42b7c94ee9be09e8d984ca980e6e64e
1 file changed
+15
compiler/forget/crates/forget_semantic_analysis/src/analyzer.rs
+15
@@ -259,6 +259,7 @@ impl Visitor2 for Analyzer {
259
260
fn visit_assignment_expression(&mut self, ast: &forget_estree::AssignmentExpression) {
261
if ast.operator == AssignmentOperator::Equals {
262
+ // "=" operator is a reassignment, straightforward
263
match &ast.left {
264
AssignmentTarget::Pattern(left) => {
265
Analyzer::visit_declaration_pattern(self, left, None);
@@ -313,6 +314,8 @@ impl Visitor2 for Analyzer {
314
}
315
self.visit_expression(&ast.right);
316
} else {
317
+ // otherwise this is a update operator which reads and updates the value.
318
+ // the left-hand side must be an identifier, which is a ReadWrite reference.
319
let left: &Identifier;
320
if let AssignmentTarget::Pattern(pat) = &ast.left {
321
if let Pattern::Identifier(pat) = pat {
@@ -347,6 +350,9 @@ impl Visitor2 for Analyzer {
350
}
351
352
fn visit_block_statement(&mut self, ast: &forget_estree::BlockStatement) {
353
+ // Block statements create a new scope. In cases where we want to avoid
354
+ // the new scope, such as function declarations, we avoid calling this
355
+ // method and visit the block contents directly.
356
self.enter(ScopeKind::Block, |visitor| {
357
for stmt in &ast.body {
358
visitor.visit_statement(stmt);
@@ -387,6 +393,8 @@ impl Visitor2 for Analyzer {
393
}
394
395
fn visit_catch_clause(&mut self, ast: &forget_estree::CatchClause) {
396
+ // If a catch clause has a param for the value being caught, then
397
+ // a new scope is created for that param.
398
if let Some(param) = &ast.param {
399
self.enter(ScopeKind::CatchClause, |visitor| {
400
Analyzer::visit_declaration_pattern(
@@ -480,6 +488,13 @@ impl Visitor2 for Analyzer {
488
}
489
490
fn visit_identifier(&mut self, ast: &forget_estree::Identifier) {
491
+ // `Identifier` is tricky in ESTree, because the same node type is used
492
+ // for places that reference variables as those that are string names:
493
+ // `x` is an Identifier, but so is the "y" in `x.y`.
494
+ // We're careful to skip visiting any Identifier that is not a variable
495
+ // reference, such that if we reach here it *should* be a variable
496
+ // reference. We also take a different path for variable assignment so
497
+ // that this must be a variable read.
498
Analyzer::visit_reference_identifier(
499
self,
500
&ast.name,