/** * If we haven't found a return value yet, try to look at the "return" statements in the function. */ FunctionTypeBuilder inferReturnStatementsAsLastResort(@Nullable Node functionBlock) { if (functionBlock == null || compiler.getInput(sourceName).isExtern()) { return this; } Preconditions.checkArgument(functionBlock.getType() == Token.BLOCK); if (returnType == null) { boolean hasNonEmptyReturns = false; List<Node> worklist = Lists.newArrayList(functionBlock); while (!worklist.isEmpty()) { Node current = worklist.remove(worklist.size() - 1); int cType = current.getType(); if (cType == Token.RETURN && current.getFirstChild() != null || cType == Token.THROW) { hasNonEmptyReturns = true; break; } else if (NodeUtil.isStatementBlock(current) || NodeUtil.isControlStructure(current)) { for (Node child = current.getFirstChild(); child != null; child = child.getNext()) { worklist.add(child); } } } if (!hasNonEmptyReturns) { returnType = typeRegistry.getNativeType(VOID_TYPE); returnTypeInferred = true; } } return this; }
/** * Declares a variable. * * @param name The variable name * @param n The node corresponding to the variable name (usually a NAME node) * @param parent The parent node of {@code n} * @param gramps The parent node of {@code parent} * @param declaredType The variable's type, according to JSDoc * @param nodeWithLineNumber The node to use to access the line number of the variable * declaration, if needed */ private void declareVar( String name, Node n, Node parent, Node gramps, JSType declaredType, Node nodeWithLineNumber) { if (scope.isDeclared(name, false) || (scope.isLocal() && name.equals(ARGUMENTS))) { redeclarationHandler.onRedeclaration(scope, name, n, parent, gramps, nodeWithLineNumber); } else { scope.declare(name, n, declaredType, compiler.getInput(sourceName)); } }
/** * Declares a variable. * * @param n The node corresponding to the variable name. */ private void declareVar(Node n) { Preconditions.checkState(n.isName()); CompilerInput input = compiler.getInput(inputId); String name = n.getString(); if (scope.isDeclared(name, false) || (scope.isLocal() && name.equals(ARGUMENTS))) { redeclarationHandler.onRedeclaration(scope, name, n, input); } else { if (isTyped) { ((TypedScope) scope).declare(name, n, null, input); } else { scope.declare(name, n, input); } } }
private void addThisVar(NodeTraversal t) { Scope scope = t.getScope(); if (scope.isDeclared(THIS_VAR, false)) { return; } Node parent = t.getScopeRoot(); if (parent.isFunction()) { // Add the new node at the beginning of the function body. parent = parent.getLastChild(); } if (parent.isSyntheticBlock()) { // Add the new node inside the SCRIPT node instead of the // synthetic block that contains it. parent = parent.getFirstChild(); } Node name = IR.name(THIS_VAR).srcref(parent); Node thisVar = IR.var(name, IR.thisNode().srcref(parent)); thisVar.srcref(parent); parent.addChildToFront(thisVar); scope.declare(THIS_VAR, name, null, compiler.getInput(parent.getInputId())); }
private void addVarDecls(NodeTraversal t, boolean addThis, boolean addArguments) { Scope scope = t.getScope(); if (scope.isDeclared(THIS_VAR, false)) { addThis = false; } if (scope.isDeclared(ARGUMENTS_VAR, false)) { addArguments = false; } Node parent = t.getScopeRoot(); if (parent.isFunction()) { // Add the new node at the beginning of the function body. parent = parent.getLastChild(); } if (parent.isSyntheticBlock() && parent.getFirstChild().isScript()) { // Add the new node inside the SCRIPT node instead of the // synthetic block that contains it. parent = parent.getFirstChild(); } CompilerInput input = compiler.getInput(parent.getInputId()); if (addArguments) { Node name = IR.name(ARGUMENTS_VAR).srcref(parent); Node argumentsVar = IR.var(name, IR.name("arguments").srcref(parent)); argumentsVar.srcref(parent); parent.addChildToFront(argumentsVar); scope.declare(ARGUMENTS_VAR, name, null, input); } if (addThis) { Node name = IR.name(THIS_VAR).srcref(parent); Node thisVar = IR.var(name, IR.thisNode().srcref(parent)); thisVar.srcref(parent); parent.addChildToFront(thisVar); scope.declare(THIS_VAR, name, null, input); } }
JSModule getRefModule(ReferenceCollectingCallback.Reference ref) { CompilerInput input = compiler.getInput(ref.getInputId()); return input == null ? null : input.getModule(); }
/** Gets the current input source. */ public CompilerInput getInput() { return compiler.getInput(inputId); }