Search in sources :

Example 6 with Token

use of com.google.javascript.rhino.Token in project closure-compiler by google.

the class Denormalize method maybeCollapseLogicalAssignShorthand.

private void maybeCollapseLogicalAssignShorthand(NodeTraversal t, Node n, Node parent) {
    if (!isCollapsableLogicalAssign(n)) {
        return;
    }
    Node op = n.getLastChild();
    Token assignOp = getAssignOpFromOp(n);
    if (n.getFirstChild().getString().equals(op.getFirstChild().getString())) {
        op.setToken(assignOp);
        Node opDetached = op.detach();
        opDetached.setJSDocInfo(n.getJSDocInfo());
        n.replaceWith(opDetached);
        NodeUtil.addFeatureToScript(t.getCurrentScript(), Feature.LOGICAL_ASSIGNMENT, compiler);
        compiler.reportChangeToEnclosingScope(parent);
    }
}
Also used : Node(com.google.javascript.rhino.Node) Token(com.google.javascript.rhino.Token)

Example 7 with Token

use of com.google.javascript.rhino.Token in project closure-compiler by google.

the class NodeIteratorsTest method testVarMotionWithCode.

/**
 * @see #testVarMotionWithCode(String, Token ...)
 */
private void testVarMotionWithCode(String code, List<Token> expectedTokens) {
    List<Node> ancestors = new ArrayList<>();
    // Add an empty node to the beginning of the code and start there.
    Compiler compiler = new Compiler();
    Node root = compiler.parseTestCode(";" + code);
    for (Node n = root; n != null; n = n.getFirstChild()) {
        ancestors.add(0, n);
    }
    FunctionlessLocalScope searchIt = new FunctionlessLocalScope(ancestors.toArray(new Node[0]));
    boolean found = false;
    while (searchIt.hasNext()) {
        Node n = searchIt.next();
        if (n.isName() && NodeUtil.isNameDeclaration(searchIt.currentParent()) && n.getString().equals("X")) {
            found = true;
            break;
        }
    }
    assertWithMessage("Variable X not found! " + root.toStringTree()).that(found).isTrue();
    List<Node> currentAncestors = searchIt.currentAncestors();
    assertThat(currentAncestors.size()).isAtLeast(3);
    Iterator<Node> moveIt = LocalVarMotion.forVar(compiler, currentAncestors.get(0), currentAncestors.get(1), currentAncestors.get(2));
    List<Token> actualTokens = new ArrayList<>();
    while (moveIt.hasNext()) {
        actualTokens.add(moveIt.next().getToken());
    }
    assertThat(actualTokens).isEqualTo(expectedTokens);
}
Also used : Node(com.google.javascript.rhino.Node) ArrayList(java.util.ArrayList) Token(com.google.javascript.rhino.Token) FunctionlessLocalScope(com.google.javascript.jscomp.NodeIterators.FunctionlessLocalScope)

Example 8 with Token

use of com.google.javascript.rhino.Token in project closure-compiler by google.

the class InferConsts method isInferredConst.

private static boolean isInferredConst(Var v, ReferenceCollection refCollection) {
    Node nameNode = v.getNameNode();
    if (nameNode == null || refCollection == null || !refCollection.isAssignedOnceInLifetime()) {
        return false;
    }
    if (v.isImplicitGoogNamespace()) {
        return false;
    }
    Token declarationType = v.declarationType();
    switch(declarationType) {
        case LET:
            // Check that non-destructuring let names are actually assigned at declaration.
            return !nameNode.getParent().isLet() || nameNode.hasChildren();
        case CONST:
        case CATCH:
        case CLASS:
        // Parameters cannot be referenced before declaration.
        case PARAM_LIST:
        case // Function hoisting means no references before declaration.
        FUNCTION:
            return true;
        case IMPORT:
            // TODO(lharker): make this check smarter if we start optimizing unrewritten modules.
            return false;
        case VAR:
            // reference.
            return refCollection.firstReferenceIsAssigningDeclaration() && refCollection.isWellDefined();
        default:
            throw new IllegalStateException("Unrecognized declaration type " + declarationType);
    }
}
Also used : Node(com.google.javascript.rhino.Node) Token(com.google.javascript.rhino.Token)

Example 9 with Token

use of com.google.javascript.rhino.Token in project closure-compiler by google.

the class RemoveUnusedCode method traverseNode.

/**
 * Traverses everything in the current scope and marks variables that are referenced.
 *
 * <p>During traversal, we identify subtrees that will only be referenced if their enclosing
 * variables are referenced. Instead of traversing those subtrees, we create a continuation for
 * them, and traverse them lazily.
 */
private void traverseNode(Node n, Scope scope) {
    Node parent = n.getParent();
    Token type = n.getToken();
    switch(type) {
        case CATCH:
            traverseCatch(n, scope);
            break;
        case FUNCTION:
            {
                VarInfo varInfo = null;
                // for it instead of traversing immediately.
                if (NodeUtil.isFunctionDeclaration(n)) {
                    varInfo = traverseNameNode(n.getFirstChild(), scope);
                    FunctionDeclaration functionDeclaration = new RemovableBuilder().addContinuation(new Continuation(n, scope)).buildFunctionDeclaration(n);
                    varInfo.addRemovable(functionDeclaration);
                    if (parent.isExport()) {
                        varInfo.setIsExplicitlyNotRemovable();
                    }
                } else {
                    traverseFunction(n, scope);
                }
            }
            break;
        case ASSIGN:
            traverseAssign(n, scope);
            break;
        case ASSIGN_BITOR:
        case ASSIGN_BITXOR:
        case ASSIGN_BITAND:
        case ASSIGN_LSH:
        case ASSIGN_RSH:
        case ASSIGN_URSH:
        case ASSIGN_ADD:
        case ASSIGN_SUB:
        case ASSIGN_MUL:
        case ASSIGN_EXPONENT:
        case ASSIGN_DIV:
        case ASSIGN_MOD:
            traverseCompoundAssign(n, scope);
            break;
        case INC:
        case DEC:
            traverseIncrementOrDecrementOp(n, scope);
            break;
        case CALL:
        case OPTCHAIN_CALL:
            traverseCall(n, scope);
            break;
        case SWITCH:
        case BLOCK:
            // This case if for if there are let and const variables in block scopes.
            // Otherwise other variables will be hoisted up into the global scope and already be
            // handled.
            traverseChildren(n, NodeUtil.createsBlockScope(n) ? scopeCreator.createScope(n, scope) : scope);
            break;
        case MODULE_BODY:
            traverseChildren(n, scopeCreator.createScope(n, scope));
            break;
        case CLASS:
            traverseClass(n, scope);
            break;
        case CLASS_MEMBERS:
            traverseClassMembers(n, scope);
            break;
        case ARRAY_PATTERN:
        case PARAM_LIST:
            traverseIndirectAssignmentList(n, scope);
            break;
        case OBJECT_PATTERN:
            traverseObjectPattern(n, scope);
            break;
        case OBJECTLIT:
            traverseObjectLiteral(n, scope);
            break;
        case FOR:
            traverseVanillaFor(n, scope);
            break;
        case FOR_IN:
        case FOR_OF:
        case FOR_AWAIT_OF:
            traverseEnhancedFor(n, scope);
            break;
        case LET:
        case CONST:
        case VAR:
            // for-loop cases are handled by custom traversal methods.
            checkState(NodeUtil.isStatement(n));
            traverseDeclarationStatement(n, scope);
            break;
        case INSTANCEOF:
            traverseInstanceof(n, scope);
            break;
        case NAME:
            // The only cases that should reach this point are parameter declarations and references
            // to names. The name node does not have children in these cases.
            checkState(!n.hasChildren());
            // the parameter declaration is not a read of the name
            if (!parent.isParamList()) {
                // var|let|const name;
                // are handled at a higher level.
                checkState(!NodeUtil.isNameDeclaration(parent));
                // function name() {}
                // class name() {}
                // handled at a higher level
                checkState(!((parent.isFunction() || parent.isClass()) && parent.getFirstChild() == n));
                traverseNameNode(n, scope).setIsExplicitlyNotRemovable();
            }
            break;
        case GETPROP:
        case OPTCHAIN_GETPROP:
            traverseNormalOrOptChainGetProp(n, scope);
            break;
        default:
            traverseChildren(n, scope);
            break;
    }
}
Also used : Node(com.google.javascript.rhino.Node) Token(com.google.javascript.rhino.Token)

Example 10 with Token

use of com.google.javascript.rhino.Token in project closure-compiler by google.

the class CheckGlobalThis method shouldTraverse.

/**
 * Since this pass reports errors only when a global {@code this} keyword
 * is encountered, there is no reason to traverse non global contexts.
 */
@Override
public boolean shouldTraverse(NodeTraversal t, Node n, Node parent) {
    if (n.isFunction()) {
        // is the global "this", not an instance of Foo.
        if (n.isArrowFunction()) {
            return true;
        }
        // Don't traverse functions that are constructors or have the @this
        // or @override annotation.
        JSDocInfo jsDoc = NodeUtil.getBestJSDocInfo(n);
        if (jsDoc != null && (jsDoc.isConstructor() || jsDoc.isInterface() || jsDoc.hasThisType() || jsDoc.isOverride())) {
            return false;
        }
        if (jsDoc != null) {
            JSTypeExpression functionType = jsDoc.getType();
            if (functionType != null) {
                Node functionNode = functionType.getRoot();
                if (functionNode != null && functionNode.isFunction()) {
                    // function(this: ThisType, ...)
                    // `this:` is only allowed as the very first child of the
                    // FUNCTION node.
                    Node thisNode = functionNode.getFirstChild();
                    if (thisNode != null && thisNode.isThis()) {
                        // Type of `this` is specified, so no need to check further.
                        return false;
                    }
                }
            }
        }
        // Don't traverse functions unless they would normally
        // be able to have a @this annotation associated with them. e.g.,
        // var a = function() { }; // or
        // function a() {} // or
        // a.x = function() {}; // or
        // var a = {x: function() {}};
        Token pType = parent.getToken();
        if (!(pType == Token.BLOCK || pType == Token.SCRIPT || pType == Token.NAME || pType == Token.ASSIGN || // object literal keys
        pType == Token.STRING_KEY)) {
            return false;
        }
        // Don't traverse functions that are getting lent to a prototype.
        Node grandparent = parent.getParent();
        if (NodeUtil.mayBeObjectLitKey(parent)) {
            JSDocInfo maybeLends = grandparent.getJSDocInfo();
            if (maybeLends != null && maybeLends.hasLendsName() && maybeLends.getLendsName().getRoot().getString().endsWith(".prototype")) {
                return false;
            }
        }
    }
    if (parent != null && parent.isAssign()) {
        Node lhs = parent.getFirstChild();
        if (n == lhs) {
            // assignLhsChild should not be overridden.
            if (assignLhsChild == null) {
                assignLhsChild = lhs;
            }
        } else {
            // property or subproperty.
            if (NodeUtil.isNormalGet(lhs)) {
                if (lhs.isGetProp() && lhs.getString().equals("prototype")) {
                    return false;
                }
                Node llhs = lhs.getFirstChild();
                if (llhs.isGetProp() && llhs.getString().equals("prototype")) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : Node(com.google.javascript.rhino.Node) JSTypeExpression(com.google.javascript.rhino.JSTypeExpression) Token(com.google.javascript.rhino.Token) JSDocInfo(com.google.javascript.rhino.JSDocInfo)

Aggregations

Token (com.google.javascript.rhino.Token)35 Node (com.google.javascript.rhino.Node)29 JSType (com.google.javascript.rhino.jstype.JSType)4 Tri (com.google.javascript.jscomp.base.Tri)3 DiGraphNode (com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)3 FlowScope (com.google.javascript.jscomp.type.FlowScope)3 JSDocInfo (com.google.javascript.rhino.JSDocInfo)3 Test (org.junit.Test)3 MeasuredNode (com.google.javascript.jscomp.MinimizedCondition.MeasuredNode)2 JSType (com.google.javascript.jscomp.newtypes.JSType)2 Preconditions.checkState (com.google.common.base.Preconditions.checkState)1 Predicate (com.google.common.base.Predicate)1 HashMultiset (com.google.common.collect.HashMultiset)1 Multiset (com.google.common.collect.Multiset)1 CheckReturnValue (com.google.errorprone.annotations.CheckReturnValue)1 AssertionFunctionLookup (com.google.javascript.jscomp.CodingConvention.AssertionFunctionLookup)1 LinearFlowState (com.google.javascript.jscomp.DataFlowAnalysis.LinearFlowState)1 FunctionlessLocalScope (com.google.javascript.jscomp.NodeIterators.FunctionlessLocalScope)1 AbstractScopedCallback (com.google.javascript.jscomp.NodeTraversal.AbstractScopedCallback)1 LogFile (com.google.javascript.jscomp.diagnostic.LogFile)1