From 9218de8b55d1b1a277684765c490e56980d73224 Mon Sep 17 00:00:00 2001 From: blickly Date: Wed, 19 Jul 2017 14:33:45 -0700 Subject: [PATCH] Make more explicit which scope roots are possible in populate() This makes the code slightly longer, but I find it easier to follow. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=162537031 --- .../jscomp/Es6SyntacticScopeCreator.java | 95 +++++++++++-------- 1 file changed, 58 insertions(+), 37 deletions(-) diff --git a/src/com/google/javascript/jscomp/Es6SyntacticScopeCreator.java b/src/com/google/javascript/jscomp/Es6SyntacticScopeCreator.java index b7e861267b1..e6ad0218da6 100644 --- a/src/com/google/javascript/jscomp/Es6SyntacticScopeCreator.java +++ b/src/com/google/javascript/jscomp/Es6SyntacticScopeCreator.java @@ -122,46 +122,67 @@ void populate() { // If we are populating the global scope, inputId will be null, and need to be set // as we enter each SCRIPT node. inputId = NodeUtil.getInputId(n); - if (n.isFunction()) { - // TODO(johnlenz): inputId maybe null if the FUNCTION node is detached - // from the AST. - // Is it meaningful to build a scope for detached FUNCTION node? - - final Node fnNameNode = n.getFirstChild(); - final Node args = fnNameNode.getNext(); - - // Bleed the function name into the scope, if it hasn't - // been declared in the outer scope. - String fnName = fnNameNode.getString(); - if (!fnName.isEmpty() && NodeUtil.isFunctionExpression(n)) { - declareVar(scope, fnNameNode); + switch (n.getToken()) { + case FUNCTION: { + // TODO(johnlenz): inputId maybe null if the FUNCTION node is detached + // from the AST. + // Is it meaningful to build a scope for detached FUNCTION node? + + final Node fnNameNode = n.getFirstChild(); + final Node args = fnNameNode.getNext(); + + // Bleed the function name into the scope, if it hasn't + // been declared in the outer scope. + String fnName = fnNameNode.getString(); + if (!fnName.isEmpty() && NodeUtil.isFunctionExpression(n)) { + declareVar(scope, fnNameNode); + } + + // Args: Declare function variables + checkState(args.isParamList()); + declareLHS(scope, args); + // Since we create a separate scope for body, stop scanning here + return; } - // Args: Declare function variables - checkState(args.isParamList()); - declareLHS(scope, args); - // Since we create a separate scope for body, stop scanning here - - } else if (n.isClass()) { - final Node classNameNode = n.getFirstChild(); - // Bleed the class name into the scope, if it hasn't - // been declared in the outer scope. - if (!classNameNode.isEmpty() && NodeUtil.isClassExpression(n)) { - declareVar(scope, classNameNode); + case CLASS: { + final Node classNameNode = n.getFirstChild(); + // Bleed the class name into the scope, if it hasn't + // been declared in the outer scope. + if (!classNameNode.isEmpty() && NodeUtil.isClassExpression(n)) { + declareVar(scope, classNameNode); + } + return; } - } else if (n.isRoot() - || n.isNormalBlock() - || NodeUtil.isAnyFor(n) - || n.isSwitch() - || n.isModuleBody()) { - boolean isHoistScope = - n.isRoot() || NodeUtil.isFunctionBlock(n) || n.isModuleBody(); - Scope hoistScope = isHoistScope ? scope : null; - scanVars(n, hoistScope, scope); - } else { - // n is the global scope - checkState(scope.isGlobal(), scope); - scanVars(n, scope, scope); + + case ROOT: + case SCRIPT: + // n is the global scope + checkState(scope.isGlobal(), scope); + scanVars(n, scope, scope); + return; + + case MODULE_BODY: + scanVars(n, scope, scope); + return; + + case FOR: + case FOR_OF: + case FOR_IN: + case SWITCH: + scanVars(n, null, scope); + return; + + case BLOCK: + if (NodeUtil.isFunctionBlock(n)) { + scanVars(n, scope, scope); + } else { + scanVars(n, null, scope); + } + return; + + default: + throw new RuntimeException("Illegal scope root: " + n); } }