Search in sources :

Example 1 with Token

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

the class SideEffectsAnalysis method nodesHaveSameControlFlow.

/**
 * Returns true if the two nodes have the same control flow properties,
 * that is, is node1 be executed every time node2 is executed and vice versa?
 */
private static boolean nodesHaveSameControlFlow(Node node1, Node node2) {
    /*
     * We conservatively approximate this with the following criteria:
     *
     * Define the "deepest control dependent block" for a node to be the
     * closest ancestor whose *parent* is a control structure and where that
     * ancestor may or may be executed depending on the parent.
     *
     * So, for example, in:
     * if (a) {
     *  b;
     * } else {
     *  c;
     * }
     *
     * a has not deepest control dependent block.
     * b's deepest control dependent block is the "then" block of the IF.
     * c's deepest control dependent block is the "else" block of the IF.
     *
     * We'll say two nodes have the same control flow if
     *
     * 1) they have the same deepest control dependent block
     * 2) that block is either a CASE (which can't have early exits) or it
     * doesn't have any early exits (e.g. breaks, continues, returns.)
     *
     */
    Node node1DeepestControlDependentBlock = closestControlDependentAncestor(node1);
    Node node2DeepestControlDependentBlock = closestControlDependentAncestor(node2);
    if (node1DeepestControlDependentBlock == node2DeepestControlDependentBlock) {
        if (node2DeepestControlDependentBlock != null) {
            // TODO(dcc): be less conservative about movement within CASE
            if (node2DeepestControlDependentBlock.isCase()) {
                return false;
            }
            // Don't allow breaks, continues, returns in control dependent
            // block because we don't actually create a control-flow graph
            // and so don't know if early exits site between the source
            // and the destination.
            // 
            // This is overly conservative as it doesn't allow, for example,
            // moving in the following case:
            // while (a) {
            // source();
            // 
            // while(b) {
            // break;
            // }
            // 
            // destination();
            // }
            // 
            // To fully support this kind of movement, we'll probably have to use
            // a CFG-based analysis rather than just looking at the AST.
            // 
            // TODO(dcc): have nodesHaveSameControlFlow() use a CFG
            Predicate<Node> isEarlyExitPredicate = new Predicate<Node>() {

                @Override
                public boolean apply(Node input) {
                    Token nodeType = input.getToken();
                    return nodeType == Token.RETURN || nodeType == Token.BREAK || nodeType == Token.CONTINUE;
                }
            };
            return !NodeUtil.has(node2DeepestControlDependentBlock, isEarlyExitPredicate, NOT_FUNCTION_PREDICATE);
        } else {
            return true;
        }
    } else {
        return false;
    }
}
Also used : Node(com.google.javascript.rhino.Node) Token(com.google.javascript.rhino.Token) Predicate(com.google.common.base.Predicate)

Example 2 with Token

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

the class SemanticReverseAbstractInterpreterTest method testInequalitiesCondition1.

/**
 * Tests reverse interpretation of a COMPARE(NAME, NUMBER) expression,
 * where COMPARE can be LE, LT, GE or GT.
 */
@SuppressWarnings("unchecked")
public void testInequalitiesCondition1() {
    for (Token op : Arrays.asList(Token.LT, Token.GT, Token.LE, Token.GE)) {
        FlowScope blind = newScope();
        testBinop(blind, op, createVar(blind, "a", createUnionType(STRING_TYPE, VOID_TYPE)), createNumber(8), ImmutableSet.of(new TypedName("a", STRING_TYPE)), ImmutableSet.of(new TypedName("a", createUnionType(STRING_TYPE, VOID_TYPE))));
    }
}
Also used : Token(com.google.javascript.rhino.Token) FlowScope(com.google.javascript.jscomp.type.FlowScope)

Example 3 with Token

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

the class LateEs6ToEs3Converter method visitObjectWithComputedProperty.

/**
 * Transpiles an object node with computed property,
 * and add type information to the new nodes if this pass ran after type checking.
 * For example,<pre>   {@code
 *   var obj = {a: 1, [i++]: 2}
 *   is transpiled to
 *   var $jscomp$compprop0 = {};
 *   var obj = ($jscomp$compprop0.a = 1, ($jscomp$compprop0[i++] = 2, $jscomp$compprop0));
 * }</pre>
 * Note that when adding type information to the nodes, the NAME node $jscomp$compprop0
 * would always be assigned the type of the entire object (in the above example {a: number}).
 * This is because we do not have sufficient type information during transpilation to know,
 * for example, $jscomp$compprop0 has type Object{} in the expression $jscomp$compprop0.a = 1
 */
private void visitObjectWithComputedProperty(Node obj) {
    checkArgument(obj.isObjectLit());
    List<Node> props = new ArrayList<>();
    Node currElement = obj.getFirstChild();
    TypeI objectType = obj.getTypeI();
    while (currElement != null) {
        if (currElement.getBooleanProp(Node.COMPUTED_PROP_GETTER) || currElement.getBooleanProp(Node.COMPUTED_PROP_SETTER)) {
            Es6ToEs3Util.cannotConvertYet(compiler, currElement, "computed getter/setter in an object literal");
            return;
        } else if (currElement.isGetterDef() || currElement.isSetterDef()) {
            currElement = currElement.getNext();
        } else {
            Node nextNode = currElement.getNext();
            obj.removeChild(currElement);
            props.add(currElement);
            currElement = nextNode;
        }
    }
    String objName = FRESH_COMP_PROP_VAR + compiler.getUniqueNameIdSupplier().get();
    props = Lists.reverse(props);
    Node result = withType(IR.name(objName), objectType);
    for (Node propdef : props) {
        if (propdef.isComputedProp()) {
            Node propertyExpression = propdef.removeFirstChild();
            Node value = propdef.removeFirstChild();
            TypeI valueType = value.getTypeI();
            result = withType(IR.comma(withType(IR.assign(withUnknownType(IR.getelem(withType(IR.name(objName), objectType), propertyExpression)), value), valueType), result), objectType);
        } else {
            Node val = propdef.removeFirstChild();
            TypeI valueType = val.getTypeI();
            propdef.setToken(Token.STRING);
            propdef.setTypeI(null);
            Token token = propdef.isQuotedString() ? Token.GETELEM : Token.GETPROP;
            Node access = withType(new Node(token, withType(IR.name(objName), objectType), propdef), valueType);
            result = withType(IR.comma(withType(IR.assign(access, val), valueType), result), objectType);
        }
    }
    Node statement = obj;
    while (!NodeUtil.isStatement(statement)) {
        statement = statement.getParent();
    }
    result.useSourceInfoIfMissingFromForTree(obj);
    obj.replaceWith(result);
    TypeI simpleObjectType = createType(addTypes, registry, JSTypeNative.EMPTY_OBJECT_LITERAL_TYPE);
    Node var = IR.var(withType(IR.name(objName), objectType), withType(obj, simpleObjectType));
    var.useSourceInfoIfMissingFromForTree(statement);
    statement.getParent().addChildBefore(var, statement);
    compiler.reportChangeToEnclosingScope(var);
}
Also used : Node(com.google.javascript.rhino.Node) TypeI(com.google.javascript.rhino.TypeI) ArrayList(java.util.ArrayList) Token(com.google.javascript.rhino.Token)

Example 4 with Token

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

the class NodeTraversal method traverseBranch.

/**
 * Traverses a branch.
 */
private void traverseBranch(Node n, Node parent) {
    Token type = n.getToken();
    if (type == Token.SCRIPT) {
        handleScript(n, parent);
        return;
    } else if (type == Token.FUNCTION) {
        handleFunction(n, parent);
        return;
    }
    curNode = n;
    if (!callback.shouldTraverse(this, n, parent)) {
        return;
    }
    if (type == Token.CLASS) {
        traverseClass(n);
    } else if (type == Token.MODULE_BODY) {
        traverseModule(n);
    } else if (useBlockScope && NodeUtil.createsBlockScope(n)) {
        traverseBlockScope(n);
    } else {
        traverseChildren(n);
    }
    curNode = n;
    callback.visit(this, n, parent);
}
Also used : Token(com.google.javascript.rhino.Token)

Example 5 with Token

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

the class PeepholeMinimizeConditions method tryMinimizeNot.

/**
 * Try to minimize NOT nodes such as !(x==y).
 *
 * Returns the replacement for n or the original if no change was made
 */
private Node tryMinimizeNot(Node n) {
    checkArgument(n.isNot());
    Node parent = n.getParent();
    Node notChild = n.getFirstChild();
    // negative operator of the current one : == -> != for instance.
    Token complementOperator;
    switch(notChild.getToken()) {
        case EQ:
            complementOperator = Token.NE;
            break;
        case NE:
            complementOperator = Token.EQ;
            break;
        case SHEQ:
            complementOperator = Token.SHNE;
            break;
        case SHNE:
            complementOperator = Token.SHEQ;
            break;
        // GT, GE, LT, LE are not handled in this because !(x<NaN) != x>=NaN.
        default:
            return n;
    }
    Node newOperator = n.removeFirstChild();
    newOperator.setToken(complementOperator);
    parent.replaceChild(n, newOperator);
    compiler.reportChangeToEnclosingScope(parent);
    return newOperator;
}
Also used : MeasuredNode(com.google.javascript.jscomp.MinimizedCondition.MeasuredNode) Node(com.google.javascript.rhino.Node) Token(com.google.javascript.rhino.Token)

Aggregations

Token (com.google.javascript.rhino.Token)33 Node (com.google.javascript.rhino.Node)26 DiGraphNode (com.google.javascript.jscomp.graph.DiGraph.DiGraphNode)3 FlowScope (com.google.javascript.jscomp.type.FlowScope)3 TernaryValue (com.google.javascript.rhino.jstype.TernaryValue)3 MeasuredNode (com.google.javascript.jscomp.MinimizedCondition.MeasuredNode)2 JSType (com.google.javascript.jscomp.newtypes.JSType)2 JSDocInfo (com.google.javascript.rhino.JSDocInfo)2 TypeI (com.google.javascript.rhino.TypeI)2 JSType (com.google.javascript.rhino.jstype.JSType)2 ArrayList (java.util.ArrayList)2 Predicate (com.google.common.base.Predicate)1 FunctionlessLocalScope (com.google.javascript.jscomp.NodeIterators.FunctionlessLocalScope)1 TypeEnv (com.google.javascript.jscomp.newtypes.TypeEnv)1 ObjectTypeI (com.google.javascript.rhino.ObjectTypeI)1 TypeIRegistry (com.google.javascript.rhino.TypeIRegistry)1 Nullable (javax.annotation.Nullable)1