Java Code Examples for com.google.javascript.rhino.Node#getChildAtIndex()
The following examples show how to use
com.google.javascript.rhino.Node#getChildAtIndex() .
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: Closure_108_ScopedAliases_s.java From coming with MIT License | 6 votes |
private void validateScopeCall(NodeTraversal t, Node n, Node parent) { if (preprocessorSymbolTable != null) { preprocessorSymbolTable.addReference(n.getFirstChild()); } if (!parent.isExprResult()) { report(t, n, GOOG_SCOPE_USED_IMPROPERLY); } if (n.getChildCount() != 2) { // The goog.scope call should have exactly 1 parameter. The first // child is the "goog.scope" and the second should be the parameter. report(t, n, GOOG_SCOPE_HAS_BAD_PARAMETERS); } else { Node anonymousFnNode = n.getChildAtIndex(1); if (!anonymousFnNode.isFunction() || NodeUtil.getFunctionName(anonymousFnNode) != null || NodeUtil.getFunctionParameters(anonymousFnNode).hasChildren()) { report(t, anonymousFnNode, GOOG_SCOPE_HAS_BAD_PARAMETERS); } else { scopeCalls.add(n); } } }
Example 2
Source File: AstValidator.java From astor with GNU General Public License v2.0 | 5 votes |
private void validateTry(Node n) { validateNodeType(Token.TRY, n); validateMinimumChildCount(n, 2); validateMaximumChildCount(n, 3); validateBlock(n.getFirstChild()); boolean seenCatchOrFinally = false; // Validate catch Node catches = n.getChildAtIndex(1); validateNodeType(Token.BLOCK, catches); validateMaximumChildCount(catches, 1); if (catches.hasChildren()) { validateCatch(catches.getFirstChild()); seenCatchOrFinally = true; } // Validate finally if (n.getChildCount() == 3) { validateBlock(n.getLastChild()); seenCatchOrFinally = true; } if (!seenCatchOrFinally) { violation("Missing catch or finally for try statement.", n); } }
Example 3
Source File: MinerrPass.java From ng-closure-runner with MIT License | 5 votes |
@Override public void process(Node externs, Node root) { NodeTraversal.traverse(compiler, root, this); boolean codeChanged = false; PrintStream stream; for (Node instance : minerrInstances) { Node templateNode = instance.getChildAtIndex(2); Node errCodeNode = instance.getChildAtIndex(1); String namespace = getNamespace(instance); if (namespace != null) { addMessageToNamespace(namespace, getExprString(errCodeNode), getExprString(templateNode)); } else { addMessageToGlobalNamespace(getExprString(errCodeNode), getExprString(templateNode)); } instance.removeChild(templateNode); codeChanged = true; } if (minerrDefNode != null && minerrDefSource != null) { Node newMinErrDef = createSubstituteMinerrDefinition(); newMinErrDef.useSourceInfoFromForTree(minerrDefNode); minerrDefNode.getParent().replaceChild(minerrDefNode, newMinErrDef); codeChanged = true; } Map<String, Object> jsonBuilder = new HashMap<String, Object>(namespaces); jsonBuilder.putAll(globalNamespace); JSONObject json = new JSONObject(jsonBuilder); errorConfigOutput.print(json.toString()); if (codeChanged) { compiler.reportCodeChange(); } }
Example 4
Source File: ReplaceMessages.java From astor with GNU General Public License v2.0 | 5 votes |
@Override void processMessageFallback( Node callNode, JsMessage message1, JsMessage message2) { boolean isFirstMessageTranslated = (bundle.getMessage(message1.getId()) != null); boolean isSecondMessageTranslated = (bundle.getMessage(message2.getId()) != null); Node replacementNode = isSecondMessageTranslated && !isFirstMessageTranslated ? callNode.getChildAtIndex(2) : callNode.getChildAtIndex(1); callNode.getParent().replaceChild(callNode, replacementNode.detachFromParent()); }
Example 5
Source File: SpecializeModule.java From astor with GNU General Public License v2.0 | 5 votes |
/** * Returns true if the function can be fixed up (that is, if it can be * safely removed or specialized). * * <p>In order to be safely fixed up, a function must be: * <PRE> * - in the global scope * - not aliased in the initial module * - of one of the following forms: * function f() {} * var f = function() {} * f = function(){} * var ns = {}; ns.f = function() {} * SomeClass.prototype.foo = function() {}; * </PRE> * * <p>Anonymous functions cannot be safely fixed up, nor can functions * that have been aliased. * * <p>Some functions declared as object literals could be safely fixed up, * however we do not currently support this. */ public boolean canFixupFunction(Node functionNode) { Preconditions.checkArgument(functionNode.isFunction()); if (!nodeIsInGlobalScope(functionNode) || initialModuleAliasAnalysis.isAliased(functionNode)) { return false; } if (NodeUtil.isStatement(functionNode)) { // function F() {} return true; } Node parent = functionNode.getParent(); Node gramps = parent.getParent(); if (parent.isName() && gramps.isVar()) { // var f = function() {} return true; } if (NodeUtil.isExprAssign(gramps) && parent.getChildAtIndex(1) == functionNode) { // f = function() {} // ns.f = function() {} return true; } return false; }
Example 6
Source File: Closure_35_TypeInference_t.java From coming with MIT License | 5 votes |
/** * For functions with function parameters, type inference will set the type of * a function literal argument from the function parameter type. */ private void updateTypeOfParameters(Node n, FunctionType fnType) { int i = 0; int childCount = n.getChildCount(); for (Node iParameter : fnType.getParameters()) { if (i + 1 >= childCount) { // TypeCheck#visitParametersList will warn so we bail. return; } JSType iParameterType = getJSType(iParameter); Node iArgument = n.getChildAtIndex(i + 1); JSType iArgumentType = getJSType(iArgument); inferPropertyTypesToMatchConstraint(iArgumentType, iParameterType); if (iParameterType.isFunctionType()) { FunctionType iParameterFnType = iParameterType.toMaybeFunctionType(); if (iArgument.isFunction() && iArgumentType.isFunctionType() && iArgument.getJSDocInfo() == null) { iArgument.setJSType(iParameterFnType); } } i++; } }
Example 7
Source File: Closure_9_ProcessCommonJSModules_s.java From coming with MIT License | 5 votes |
/** * Rewrite module.exports to moduleName.module$exports. */ private void visitModuleExports(Node prop) { String moduleName = guessCJSModuleName(prop.getSourceFileName()); Node module = prop.getChildAtIndex(0); module.putProp(Node.ORIGINALNAME_PROP, "module"); module.setString(moduleName); Node exports = prop.getChildAtIndex(1); exports.putProp(Node.ORIGINALNAME_PROP, "exports"); exports.setString("module$exports"); modulesWithExports.add(moduleName); }
Example 8
Source File: jKali_003_s.java From coming with MIT License | 4 votes |
/** * @param n The expression to check. * @return Whether the expression is unconditionally executed only once in the * containing execution scope. */ static boolean isExecutedExactlyOnce(Node n) { inspect: do { Node parent = n.getParent(); switch (parent.getType()) { case Token.IF: case Token.HOOK: case Token.AND: case Token.OR: if (parent.getFirstChild() != n) { return false; } // other ancestors may be conditional continue inspect; case Token.FOR: if (NodeUtil.isForIn(parent)) { if (parent.getChildAtIndex(1) != n) { return false; } } else { if (parent.getFirstChild() != n) { return false; } } // other ancestors may be conditional continue inspect; case Token.WHILE: case Token.DO: return false; case Token.TRY: // Consider all code under a try/catch to be conditionally executed. if (!hasFinally(parent) || parent.getLastChild() != n) { return false; } continue inspect; case Token.CASE: case Token.DEFAULT_CASE: return false; case Token.SCRIPT: case Token.FUNCTION: // Done, we've reached the scope root. break inspect; } } while ((n = n.getParent()) != null); return true; }
Example 9
Source File: Cardumen_00200_s.java From coming with MIT License | 4 votes |
/** * @returns false iff the result of the expression is not consumed. */ static boolean isExpressionResultUsed(Node expr) { // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult. Node parent = expr.getParent(); switch (parent.getType()) { case Token.BLOCK: case Token.EXPR_RESULT: return false; case Token.HOOK: case Token.AND: case Token.OR: return (expr == parent.getFirstChild()) ? true : isExpressionResultUsed(parent); case Token.COMMA: Node gramps = parent.getParent(); if (gramps.isCall() && parent == gramps.getFirstChild()) { // Semantically, a direct call to eval is different from an indirect // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first // expression to a comma to be a no-op if it's used to indirect // an eval. This we pretend that this is "used". if (expr == parent.getFirstChild() && parent.getChildCount() == 2 && expr.getNext().isName() && "eval".equals(expr.getNext().getString())) { return true; } } return (expr == parent.getFirstChild()) ? false : isExpressionResultUsed(parent); case Token.FOR: if (!NodeUtil.isForIn(parent)) { // Only an expression whose result is in the condition part of the // expression is used. return (parent.getChildAtIndex(1) == expr); } break; } return true; }
Example 10
Source File: jKali_003_t.java From coming with MIT License | 4 votes |
/** * @returns false iff the result of the expression is not consumed. */ static boolean isExpressionResultUsed(Node expr) { // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult. Node parent = expr.getParent(); switch (parent.getType()) { case Token.BLOCK: case Token.EXPR_RESULT: return false; case Token.HOOK: case Token.AND: case Token.OR: return (expr == parent.getFirstChild()) ? true : isExpressionResultUsed(parent); case Token.COMMA: Node gramps = parent.getParent(); if (gramps.isCall() && parent == gramps.getFirstChild()) { // Semantically, a direct call to eval is different from an indirect // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first // expression to a comma to be a no-op if it's used to indirect // an eval. This we pretend that this is "used". if (expr == parent.getFirstChild() && parent.getChildCount() == 2 && expr.getNext().isName() && "eval".equals(expr.getNext().getString())) { return true; } } return (expr == parent.getFirstChild()) ? false : isExpressionResultUsed(parent); case Token.FOR: if (!NodeUtil.isForIn(parent)) { // Only an expression whose result is in the condition part of the // expression is used. return (parent.getChildAtIndex(1) == expr); } break; } return true; }
Example 11
Source File: Cardumen_0087_t.java From coming with MIT License | 4 votes |
/** * @param n The expression to check. * @return Whether the expression is unconditionally executed only once in the * containing execution scope. */ static boolean isExecutedExactlyOnce(Node n) { inspect: do { Node parent = n.getParent(); switch (parent.getType()) { case Token.IF: case Token.HOOK: case Token.AND: case Token.OR: if (parent.getFirstChild() != n) { return false; } // other ancestors may be conditional continue inspect; case Token.FOR: if (NodeUtil.isForIn(parent)) { if (parent.getChildAtIndex(1) != n) { return false; } } else { if (parent.getFirstChild() != n) { return false; } } // other ancestors may be conditional continue inspect; case Token.WHILE: case Token.DO: return false; case Token.TRY: // Consider all code under a try/catch to be conditionally executed. if (!hasFinally(parent) || parent.getLastChild() != n) { return false; } continue inspect; case Token.CASE: case Token.DEFAULT_CASE: return false; case Token.SCRIPT: case Token.FUNCTION: // Done, we've reached the scope root. break inspect; } } while ((n = n.getParent()) != null); return true; }
Example 12
Source File: Cardumen_0087_s.java From coming with MIT License | 4 votes |
/** * @param n The expression to check. * @return Whether the expression is unconditionally executed only once in the * containing execution scope. */ static boolean isExecutedExactlyOnce(Node n) { inspect: do { Node parent = n.getParent(); switch (parent.getType()) { case Token.IF: case Token.HOOK: case Token.AND: case Token.OR: if (parent.getFirstChild() != n) { return false; } // other ancestors may be conditional continue inspect; case Token.FOR: if (NodeUtil.isForIn(parent)) { if (parent.getChildAtIndex(1) != n) { return false; } } else { if (parent.getFirstChild() != n) { return false; } } // other ancestors may be conditional continue inspect; case Token.WHILE: case Token.DO: return false; case Token.TRY: // Consider all code under a try/catch to be conditionally executed. if (!hasFinally(parent) || parent.getLastChild() != n) { return false; } continue inspect; case Token.CASE: case Token.DEFAULT_CASE: return false; case Token.SCRIPT: case Token.FUNCTION: // Done, we've reached the scope root. break inspect; } } while ((n = n.getParent()) != null); return true; }
Example 13
Source File: NodeUtil.java From astor with GNU General Public License v2.0 | 4 votes |
/** * @param n The expression to check. * @return Whether the expression is unconditionally executed only once in the * containing execution scope. */ static boolean isExecutedExactlyOnce(Node n) { inspect: do { Node parent = n.getParent(); switch (parent.getType()) { case Token.IF: case Token.HOOK: case Token.AND: case Token.OR: if (parent.getFirstChild() != n) { return false; } // other ancestors may be conditional continue inspect; case Token.FOR: if (NodeUtil.isForIn(parent)) { if (parent.getChildAtIndex(1) != n) { return false; } } else { if (parent.getFirstChild() != n) { return false; } } // other ancestors may be conditional continue inspect; case Token.WHILE: case Token.DO: return false; case Token.TRY: // Consider all code under a try/catch to be conditionally executed. if (!hasFinally(parent) || parent.getLastChild() != n) { return false; } continue inspect; case Token.CASE: case Token.DEFAULT_CASE: return false; case Token.SCRIPT: case Token.FUNCTION: // Done, we've reached the scope root. break inspect; } } while ((n = n.getParent()) != null); return true; }
Example 14
Source File: NodeUtil.java From astor with GNU General Public License v2.0 | 4 votes |
/** * @returns false iff the result of the expression is not consumed. */ static boolean isExpressionResultUsed(Node expr) { // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult. Node parent = expr.getParent(); switch (parent.getType()) { case Token.BLOCK: case Token.EXPR_RESULT: return false; case Token.CAST: return isExpressionResultUsed(parent); case Token.HOOK: case Token.AND: case Token.OR: return (expr == parent.getFirstChild()) ? true : isExpressionResultUsed(parent); case Token.COMMA: Node gramps = parent.getParent(); if (gramps.isCall() && parent == gramps.getFirstChild()) { // Semantically, a direct call to eval is different from an indirect // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first // expression to a comma to be a no-op if it's used to indirect // an eval. This we pretend that this is "used". if (expr == parent.getFirstChild() && parent.getChildCount() == 2 && expr.getNext().isName() && "eval".equals(expr.getNext().getString())) { return true; } } return (expr == parent.getFirstChild()) ? false : isExpressionResultUsed(parent); case Token.FOR: if (!NodeUtil.isForIn(parent)) { // Only an expression whose result is in the condition part of the // expression is used. return (parent.getChildAtIndex(1) == expr); } break; } return true; }
Example 15
Source File: ExpandJqueryAliases.java From astor with GNU General Public License v2.0 | 4 votes |
/** * Expand a jQuery.expandedEach call * * Expanded jQuery.expandedEach calls will replace the GETELEM nodes of a * property assignment with GETPROP nodes to allow for renaming. */ private void maybeExpandJqueryEachCall(NodeTraversal t, Node n) { Node objectToLoopOver = n.getChildAtIndex(1); if (objectToLoopOver == null) { return; } Node callbackFunction = objectToLoopOver.getNext(); if (callbackFunction == null || !callbackFunction.isFunction()) { return; } // Run the peephole optimizations on the first argument to handle // cases like ("a " + "b").split(" ") peepholePasses.process(null, n.getChildAtIndex(1)); // Create a reference tree Node nClone = n.cloneTree(); objectToLoopOver = nClone.getChildAtIndex(1); // Check to see if the first argument is something we recognize and can // expand. if (!objectToLoopOver.isObjectLit() && !(objectToLoopOver.isArrayLit() && isArrayLitValidForExpansion(objectToLoopOver))) { t.report(n, JQUERY_UNABLE_TO_EXPAND_INVALID_LIT_ERROR, (String)null); return; } // Find all references to the callback function arguments List<Node> keyNodeReferences = Lists.newArrayList(); List<Node> valueNodeReferences = Lists.newArrayList(); NodeTraversal.traverse(compiler, NodeUtil.getFunctionBody(callbackFunction), new FindCallbackArgumentReferences(callbackFunction, keyNodeReferences, valueNodeReferences, objectToLoopOver.isArrayLit())); if(keyNodeReferences.size() == 0) { // We didn't do anything useful ... t.report(n, JQUERY_USELESS_EACH_EXPANSION, (String)null); return; } Node fncBlock = tryExpandJqueryEachCall(t, nClone, callbackFunction, keyNodeReferences, valueNodeReferences); if (fncBlock != null && fncBlock.hasChildren()) { replaceOriginalJqueryEachCall(n, fncBlock); } else { // We didn't do anything useful ... t.report(n, JQUERY_USELESS_EACH_EXPANSION, (String)null); } }
Example 16
Source File: Cardumen_0014_t.java From coming with MIT License | 4 votes |
/** * @returns false iff the result of the expression is not consumed. */ static boolean isExpressionResultUsed(Node expr) { // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult. Node parent = expr.getParent(); switch (parent.getType()) { case Token.BLOCK: case Token.EXPR_RESULT: return false; case Token.HOOK: case Token.AND: case Token.OR: return (expr == parent.getFirstChild()) ? true : isExpressionResultUsed(parent); case Token.COMMA: Node gramps = parent.getParent(); if (gramps.isCall() && parent == gramps.getFirstChild()) { // Semantically, a direct call to eval is different from an indirect // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first // expression to a comma to be a no-op if it's used to indirect // an eval. This we pretend that this is "used". if (expr == parent.getFirstChild() && parent.getChildCount() == 2 && expr.getNext().isName() && "eval".equals(expr.getNext().getString())) { return true; } } return (expr == parent.getFirstChild()) ? false : isExpressionResultUsed(parent); case Token.FOR: if (!NodeUtil.isForIn(parent)) { // Only an expression whose result is in the condition part of the // expression is used. return (parent.getChildAtIndex(1) == expr); } break; } return true; }
Example 17
Source File: Closure_35_TypeInference_s.java From coming with MIT License | 4 votes |
/** * For functions with function(this: T, ...) and T as parameters, type * inference will set the type of this on a function literal argument to the * the actual type of T. */ private void updateTypeOfThisOnClosure(Node n, FunctionType fnType) { // TODO(user): Make the template logic more general. if (fnType.getTemplateTypeName() == null) { return; } int i = 0; int childCount = n.getChildCount(); // Find the parameter whose type is the template type. for (Node iParameter : fnType.getParameters()) { JSType iParameterType = getJSType(iParameter).restrictByNotNullOrUndefined(); if (iParameterType.isTemplateType()) { // Find the actual type of this argument. ObjectType iArgumentType = null; if (i + 1 < childCount) { Node iArgument = n.getChildAtIndex(i + 1); iArgumentType = getJSType(iArgument) .restrictByNotNullOrUndefined() .collapseUnion() .toObjectType(); if (iArgumentType == null) { compiler.report( JSError.make(NodeUtil.getSourceName(iArgument), iArgument, TEMPLATE_TYPE_NOT_OBJECT_TYPE, getJSType(iArgument).toString())); return; } } // Find the parameter whose type is function(this: T, ...) boolean foundTemplateTypeOfThisParameter = false; int j = 0; for (Node jParameter : fnType.getParameters()) { JSType jParameterType = getJSType(jParameter).restrictByNotNullOrUndefined(); if (jParameterType.isFunctionType()) { FunctionType jParameterFnType = jParameterType.toMaybeFunctionType(); if (jParameterFnType.getTypeOfThis().equals(iParameterType)) { foundTemplateTypeOfThisParameter = true; // Find the actual type of the this argument. if (j + 1 >= childCount) { // TypeCheck#visitParameterList will warn so we bail. return; } Node jArgument = n.getChildAtIndex(j + 1); JSType jArgumentType = getJSType(jArgument); if (jArgument.isFunction() && jArgumentType.isFunctionType()) { if (iArgumentType != null && // null and undefined get filtered out above. !iArgumentType.isNoType()) { // If it's an function expression, update the type of this // using the actual type of T. FunctionType jArgumentFnType = jArgumentType.toMaybeFunctionType(); if (jArgumentFnType.getTypeOfThis().isUnknownType()) { // The new type will be picked up when we traverse the inner // function. jArgument.setJSType( registry.createFunctionTypeWithNewThisType( jArgumentFnType, iArgumentType)); } } else { // Warn if the anonymous function literal references this. if (NodeUtil.referencesThis( NodeUtil.getFunctionBody(jArgument))) { compiler.report(JSError.make(NodeUtil.getSourceName(n), n, FUNCTION_LITERAL_UNDEFINED_THIS)); } } } // TODO(user): Add code to TypeCheck to check that the // types of the arguments match. } } j++; } if (!foundTemplateTypeOfThisParameter) { compiler.report(JSError.make(NodeUtil.getSourceName(n), n, TEMPLATE_TYPE_OF_THIS_EXPECTED)); return; } } i++; } }
Example 18
Source File: jMutRepair_003_t.java From coming with MIT License | 4 votes |
/** * @returns false iff the result of the expression is not consumed. */ static boolean isExpressionResultUsed(Node expr) { // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult. Node parent = expr.getParent(); switch (parent.getType()) { case Token.BLOCK: case Token.EXPR_RESULT: return false; case Token.HOOK: case Token.AND: case Token.OR: return (expr == parent.getFirstChild()) ? true : isExpressionResultUsed(parent); case Token.COMMA: Node gramps = parent.getParent(); if (gramps.isCall() && parent == gramps.getFirstChild()) { // Semantically, a direct call to eval is different from an indirect // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first // expression to a comma to be a no-op if it's used to indirect // an eval. This we pretend that this is "used". if (expr == parent.getFirstChild() && parent.getChildCount() == 2 && expr.getNext().isName() && "eval".equals(expr.getNext().getString())) { return true; } } return (expr == parent.getFirstChild()) ? false : isExpressionResultUsed(parent); case Token.FOR: if (!NodeUtil.isForIn(parent)) { // Only an expression whose result is in the condition part of the // expression is used. return (parent.getChildAtIndex(1) == expr); } break; } return true; }
Example 19
Source File: Cardumen_00200_t.java From coming with MIT License | 4 votes |
/** * @returns false iff the result of the expression is not consumed. */ static boolean isExpressionResultUsed(Node expr) { // TODO(johnlenz): consider sharing some code with trySimpleUnusedResult. Node parent = expr.getParent(); switch (parent.getType()) { case Token.BLOCK: case Token.EXPR_RESULT: return false; case Token.HOOK: case Token.AND: case Token.OR: return (expr == parent.getFirstChild()) ? true : isExpressionResultUsed(parent); case Token.COMMA: Node gramps = parent.getParent(); if (gramps.isCall() && parent == gramps.getFirstChild()) { // Semantically, a direct call to eval is different from an indirect // call to an eval. See ECMA-262 S15.1.2.1. So it's OK for the first // expression to a comma to be a no-op if it's used to indirect // an eval. This we pretend that this is "used". if (expr == parent.getFirstChild() && parent.getChildCount() == 2 && expr.getNext().isName() && "eval".equals(expr.getNext().getString())) { return true; } } return (expr == parent.getFirstChild()) ? false : isExpressionResultUsed(parent); case Token.FOR: if (!NodeUtil.isForIn(parent)) { // Only an expression whose result is in the condition part of the // expression is used. return (parent.getChildAtIndex(1) == expr); } break; } return true; }
Example 20
Source File: Cardumen_00200_s.java From coming with MIT License | 4 votes |
/** * @param n The expression to check. * @return Whether the expression is unconditionally executed only once in the * containing execution scope. */ static boolean isExecutedExactlyOnce(Node n) { inspect: do { Node parent = n.getParent(); switch (parent.getType()) { case Token.IF: case Token.HOOK: case Token.AND: case Token.OR: if (parent.getFirstChild() != n) { return false; } // other ancestors may be conditional continue inspect; case Token.FOR: if (NodeUtil.isForIn(parent)) { if (parent.getChildAtIndex(1) != n) { return false; } } else { if (parent.getFirstChild() != n) { return false; } } // other ancestors may be conditional continue inspect; case Token.WHILE: case Token.DO: return false; case Token.TRY: // Consider all code under a try/catch to be conditionally executed. if (!hasFinally(parent) || parent.getLastChild() != n) { return false; } continue inspect; case Token.CASE: case Token.DEFAULT_CASE: return false; case Token.SCRIPT: case Token.FUNCTION: // Done, we've reached the scope root. break inspect; } } while ((n = n.getParent()) != null); return true; }