com.google.caja.parser.js.Expression

Here are the examples of the java api class com.google.caja.parser.js.Expression taken from open source projects.

1. EnvironmentData#normJs()

Project: caja
Source File: EnvironmentData.java
View license
static String normJs(String js, MessageQueue mq) throws ParseException {
    JsLexer lexer = new JsLexer(CharProducer.Factory.fromString(js, FilePosition.UNKNOWN));
    JsTokenQueue tq = new JsTokenQueue(lexer, InputSource.UNKNOWN);
    Expression e = new Parser(tq, mq).parseExpression(true);
    tq.expectEmpty();
    StringBuilder sb = new StringBuilder(js.length() + 16);
    RenderContext rc = new RenderContext(new JsMinimalPrinter(sb));
    e.render(rc);
    rc.getOut().noMoreTokens();
    return sb.toString();
}

2. ExpressionTest#assertFolded()

Project: caja
Source File: ExpressionTest.java
View license
private void assertFolded(String result, String expr, boolean isFn) throws ParseException {
    Expression input = jsExpr(fromString(expr));
    if (input instanceof Operation) {
        Operation op = (Operation) input;
        for (Expression operand : op.children()) {
            // Fold some operands so we can test negative numbers.
            if ((Operation.is(operand, Operator.NEGATION) || // and so that we can test corner cases around NaN and Infinity.
            Operation.is(operand, Operator.DIVISION)) && operand.children().get(0) instanceof NumberLiteral) {
                op.replaceChild(operand.fold(false), operand);
            }
        }
    }
    Expression actual = input.fold(isFn);
    assertEquals(expr, result, actual != null ? render(actual) : null);
}

3. VariableLiveness#processImmediatelyCalledFunction()

Project: caja
Source File: VariableLiveness.java
View license
private static LiveSet processImmediatelyCalledFunction(Operation op, LiveSet onEntry) {
    List<? extends Expression> operands = op.children();
    FunctionConstructor fn = (FunctionConstructor) operands.get(0);
    // operands are resolved before the function body is executed
    LiveSet onExit = onEntry;
    for (Expression actual : operands.subList(1, operands.size())) {
        onExit = liveness(actual, onExit).vars;
    }
    LiveSet asAResultOfCallingFn = processFunctionConstructor(fn);
    return onExit.union(asAResultOfCallingFn);
}

4. StatementSimplifier#optimizeExpressionFlow()

Project: caja
Source File: StatementSimplifier.java
View license
static Expression optimizeExpressionFlow(Expression e) {
    if (!(e instanceof Operation)) {
        return e;
    }
    Operation op = (Operation) e;
    List<? extends Expression> operands = op.children();
    Expression[] newOperands = null;
    int n = operands.size();
    for (int i = 0; i < n; ++i) {
        Expression operand = operands.get(i);
        Expression newOperand = optimizeExpressionFlow(operand);
        if (operand != newOperand) {
            if (newOperands == null) {
                newOperands = operands.toArray(new Expression[n]);
            }
            newOperands[i] = newOperand;
        }
    }
    Operator oper = op.getOperator();
    FilePosition pos = e.getFilePosition();
    if (oper != Operator.TERNARY) {
        return newOperands == null ? e : Operation.create(pos, oper, newOperands);
    }
    // (c ? x,z : y,z) -> (c ? x:y),z
    Expression[] ternaryOperands = newOperands != null ? newOperands : operands.toArray(new Expression[3]);
    Expression c = ternaryOperands[0];
    Expression x = ternaryOperands[1];
    Expression y = ternaryOperands[2];
    while (Operation.is(c, Operator.NOT)) {
        c = ((Operation) c).children().get(0);
        Expression t = x;
        x = y;
        y = t;
    }
    if (ParseTreeNodes.deepEquals(x, y)) {
        if (c.simplifyForSideEffect() == null) {
            return x;
        }
        return commaOp(pos, c, x);
    }
    if (isSimple(c)) {
        // control would never reach the second identical expression.
        if (ParseTreeNodes.deepEquals(c, x)) {
            // (c ? c : y) -> c || y     if c not side effecting
            return Operation.create(pos, Operator.LOGICAL_OR, c, y);
        } else if (ParseTreeNodes.deepEquals(c, y)) {
            // (c ? x : c) -> c && x     if c not side effecting
            return Operation.create(pos, Operator.LOGICAL_AND, c, x);
        }
    }
    // TODO(mikesamuel): if c is simple and not a global reference, optimize
    // out the common head as well.
    CommaCommonalities opt = commaCommonalities(x, y);
    if (opt != null) {
        // x and y are structurally identical.
        if (opt.aReduced == null) {
            // (c ? z: y,z)  ->  (c || y),z
            return commaOp(pos, Operation.createInfix(Operator.LOGICAL_OR, c, opt.bReduced), opt.commonTail);
        } else if (opt.bReduced == null) {
            // (c ? x,z : z)  ->  (c && x),z
            return commaOp(pos, Operation.createInfix(Operator.LOGICAL_AND, c, opt.aReduced), opt.commonTail);
        } else {
            // (c ? x,z : y,z) -> (c ? x : y),z
            return commaOp(pos, optimizeExpressionFlow(Operation.createTernary(c, opt.aReduced, opt.bReduced)), opt.commonTail);
        }
    }
    ternaryOperands[0] = c;
    ternaryOperands[1] = x;
    ternaryOperands[2] = y;
    if (x instanceof Operation && y instanceof Operation) {
        Operation xop = (Operation) x;
        Operation yop = (Operation) y;
        Operator xoper = xop.getOperator();
        if (xoper == yop.getOperator()) {
            List<? extends Expression> xoperands = xop.children();
            List<? extends Expression> yoperands = yop.children();
            int nOperands = xoperands.size();
            if (nOperands == yoperands.size()) {
                Expression xoperand0 = xoperands.get(0);
                // evaluated last regardless.
                if (nOperands == 2 && ParseTreeNodes.deepEquals(xoperands.get(1), yoperands.get(1)) && xoper.getCategory() != OperatorCategory.ASSIGNMENT && (xoper != Operator.FUNCTION_CALL || !(Operation.is(xoperand0, Operator.MEMBER_ACCESS) || Operation.is(xoperand0, Operator.SQUARE_BRACKET)))) {
                    // c ? foo(myNode) : bar(myNode)  =>  (c ? foo : bar)(myNode)
                    return Operation.create(pos, xoper, optimizeExpressionFlow(Operation.createTernary(c, xoperands.get(0), yoperands.get(0))), xoperands.get(1));
                }
                if (// Switching order of evaluation doesn't matter
                isSimple(xoperands.get(0)) && isSimple(c) && ParseTreeNodes.deepEquals(xoperands.get(0), yoperands.get(0))) {
                    // c ? (x + 1 : x + 2)  ->  x + (c ? 1 : 2)
                    if (xoper != Operator.MEMBER_ACCESS) {
                        return Operation.create(pos, xoper, xoperands.get(0), optimizeExpressionFlow(Operation.createTernary(c, xoperands.get(1), yoperands.get(1))));
                    } else {
                        Reference xref = (Reference) xoperands.get(1);
                        Reference yref = (Reference) yoperands.get(1);
                        StringLiteral xname = StringLiteral.valueOf(xref.getFilePosition(), xref.getIdentifierName());
                        StringLiteral yname = StringLiteral.valueOf(yref.getFilePosition(), yref.getIdentifierName());
                        return Operation.create(pos, Operator.SQUARE_BRACKET, xoperands.get(0), optimizeExpressionFlow(Operation.createTernary(c, xname, yname)));
                    }
                }
            }
        }
    }
    if (operands.equals(Arrays.asList(ternaryOperands))) {
        return e;
    }
    return Operation.create(pos, Operator.TERNARY, ternaryOperands);
}

5. ParseTreeKB#foldComparisonToFalsey()

Project: caja
Source File: ParseTreeKB.java
View license
private Fact foldComparisonToFalsey(ParseTreeNode n) {
    if (!(n instanceof Operation)) {
        return null;
    }
    Operation op = (Operation) n;
    Operator o = op.getOperator();
    boolean eq;
    boolean strict;
    switch(o) {
        case EQUAL:
        case STRICTLY_EQUAL:
            eq = true;
            break;
        case NOT_EQUAL:
        case STRICTLY_NOT_EQUAL:
            eq = false;
            break;
        default:
            return null;
    }
    strict = o == Operator.STRICTLY_EQUAL || o == Operator.STRICTLY_NOT_EQUAL;
    List<? extends Expression> operands = op.children();
    Expression a = operands.get(0);
    Expression b = operands.get(1);
    if (strict ? isUndefOrLiteral(a) : isNullOrUndef(a)) {
    // continue to check
    } else if (strict ? isUndefOrLiteral(b) : isNullOrUndef(b)) {
        Expression t = a;
        a = b;
        b = t;
    } else {
        return null;
    }
    Pair<Expression, Fact> fe = facts.get(this.optNodeDigest(b));
    if (fe == null) {
        return null;
    }
    Boolean bool = a.conditionResult();
    if (bool == null || bool.booleanValue() == fe.b.isTruthy()) {
        return null;
    }
    return eq ? Fact.FALSE : Fact.TRUE;
}

6. Linter#isCommaOperatorInForLoop()

Project: caja
Source File: Linter.java
View license
private static boolean isCommaOperatorInForLoop(AncestorChain<ExpressionStmt> es) {
    if (es.parent == null || !(es.parent.node instanceof ForLoop)) {
        return false;
    }
    Expression e = es.node.getExpression();
    return isCommaOperationNotEvaluatedForValue(e);
}

7. Linter#isCommaOperationNotEvaluatedForValue()

Project: caja
Source File: Linter.java
View license
private static boolean isCommaOperationNotEvaluatedForValue(Expression e) {
    if (!(e instanceof Operation)) {
        return false;
    }
    Operation op = (Operation) e;
    if (op.getOperator() != Operator.COMMA) {
        return false;
    }
    Expression left = op.children().get(0), right = op.children().get(1);
    return !shouldBeEvaluatedForValue(right) && (!shouldBeEvaluatedForValue(left) || isCommaOperationNotEvaluatedForValue(left));
}

8. VariableLiveness#processOperation()

Project: caja
Source File: VariableLiveness.java
View license
private static LiveSet processOperation(Operation op, LiveSet onEntry) {
    List<? extends Expression> operands = op.children();
    switch(op.getOperator()) {
        case TERNARY:
            ConditionalLiveSet postCond = processLogicOperand(op, 0, onEntry);
            LiveCalc postThen = liveness(operands.get(1), postCond.truthy);
            LiveCalc postElse = liveness(operands.get(2), postCond.falsey);
            return postThen.vars.intersection(postElse.vars);
        case LOGICAL_AND:
        case LOGICAL_OR:
            ConditionalLiveSet p = processCondition(op, onEntry);
            return p.truthy.intersection(p.falsey);
        case FUNCTION_CALL:
            if (operands.get(0) instanceof FunctionConstructor) {
                return processImmediatelyCalledFunction(op, onEntry);
            }
            break;
        default:
            break;
    }
    LiveSet postOperand = onEntry;
    for (Expression operand : operands) {
        postOperand = liveness(operand, postOperand).vars;
    }
    if (op instanceof AssignOperation && operands.get(0) instanceof Reference) {
        postOperand = postOperand.with((Reference) operands.get(0));
    }
    return postOperand;
}

9. ConstLocalOptimization#areSinglyInlineable()

Project: caja
Source File: ConstLocalOptimization.java
View license
private static boolean areSinglyInlineable(List<? extends Expression> exprs) {
    for (Expression e : exprs) {
        if (!isSinglyInlineable(e)) {
            return false;
        }
    }
    return true;
}

10. ConstLocalOptimization#areConst()

Project: caja
Source File: ConstLocalOptimization.java
View license
private static boolean areConst(List<? extends Expression> exprs) {
    for (Expression e : exprs) {
        if (!isConst(e)) {
            return false;
        }
    }
    return true;
}

11. JsOptimizer#jsExpr()

Project: caja
Source File: JsOptimizer.java
View license
private static Expression jsExpr(CharProducer cp, MessageQueue mq) throws ParseException {
    Parser p = jsParser(cp, mq);
    Expression e = p.parseExpression(true);
    p.getTokenQueue().expectEmpty();
    return e;
}

12. ParseTreeKB#optimizeMemberAccess()

Project: caja
Source File: ParseTreeKB.java
View license
private void optimizeMemberAccess(Scope s, Operation ma, boolean isFuzzy, boolean isLhs, boolean throwsOnUndefined, Result out) {
    StringBuilder sb = new StringBuilder();
    sb.append('(');
    Expression obj = ma.children().get(0);
    optimize(s, obj, false, false, false, false, out);
    Reference prop = (Reference) ma.children().get(1);
    if (out.node != obj) {
        ma = Operation.createInfix(Operator.MEMBER_ACCESS, (Expression) out.node, prop);
    }
    sb = addDigest(out.digest, sb);
    int objDigestEnd = sb != null ? sb.length() : -1;
    if (sb != null) {
        nodeDigest(ma.children().get(1), sb);
        nodeTail(ma, sb);
    }
    String digest = sb != null ? sb.toString() : null;
    out.node = ma;
    out.digest = digest;
    if (digest != null) {
        if (!isLhs) {
            Fact f = getFact(digest);
            if (f != null && f.isSubstitutable(isFuzzy)) {
                out.node = f.value.clone();
                out.digest = nodeDigest(out.node);
                return;
            }
        }
        // window.addEventListener -> addEventListener
        String objDigest = digest.substring(1, objDigestEnd);
        Pair<Expression, Fact> objFe = facts.get(objDigest);
        if (objFe != null && objFe.b.isGlobal() && s.isOuter(prop.getIdentifierName())) {
            String propDigest = nodeDigest(prop);
            boolean canSimplify = false;
            if (isLhs || throwsOnUndefined) {
                // If it's being set, we don't need to worry about undefined global
                // errors, and we don't need to worry if the containing expression
                // would throw if it were undefined anyway.
                canSimplify = true;
            } else {
                // No difference between foo and global.foo because foo is
                // not undefined (truthy or (falsey and not undefined).
                Pair<Expression, Fact> propFe = facts.get(propDigest);
                if (propFe != null) {
                    Fact pf = propFe.b;
                    canSimplify = pf.isTruthy() || (pf.type == Fact.Type.IS && !pf.isUndefined());
                }
            }
            if (canSimplify) {
                out.node = prop;
                out.digest = propDigest;
            }
        }
    }
}

13. ParseTreeKB#withoutTopRef()

Project: caja
Source File: ParseTreeKB.java
View license
private static Expression withoutTopRef(Expression e) {
    Operation op = (Operation) e;
    List<? extends Expression> operands = op.children();
    Expression obj = operands.get(0), prop = operands.get(1);
    if (obj instanceof Reference) {
        return prop;
    }
    return Operation.create(e.getFilePosition(), op.getOperator(), withoutTopRef(obj), prop);
}

14. StatementSimplifier#optimizeConditional()

Project: caja
Source File: StatementSimplifier.java
View license
private static Statement optimizeConditional(FilePosition parentPos, List<ParseTreeNode> condParts) {
    // We can optimize it if all the clauses are expression stmts, returns or
    // throws.
    int n = condParts.size();
    Class<? extends ParseTreeNode> clauseClass = condParts.get(1).getClass();
    boolean hasElse = (n & 1) == 1;
    if (clauseClass != ExpressionStmt.class && !(hasElse && (clauseClass == ReturnStmt.class || clauseClass == ThrowStmt.class))) {
        return null;
    }
    for (int i = 3; i < n; i += 2) {
        if (condParts.get(i).getClass() != clauseClass) {
            return null;
        }
    }
    if (hasElse && condParts.get(n - 1).getClass() != clauseClass) {
        return null;
    }
    // Now we know we can optimize because the input is:
    //   if (e0) s0; else if (e1) s1;
    //   if (e0) s0; else if (e1) s1; else s2;
    // where s0... are expression statements evaluated for their side-effects.
    // Or,
    //   if (e0) return r0; else if (e1) return r1; else return r2
    // Or,
    //   if (e0) throw ex0; else if (e1) throw ex1; else throw ex2
    // Consider 3 cases
    // Case 0:
    //   if (a) return b; else if (c) return d else return e
    //   =>   return a ? b : c ? d : e;
    // Case 1:
    //   if (a) b; else if (c) d else e
    //   =>   a ? b : c ? d : e;
    // Case 2:
    //   if (a) b; else if (c) d
    //   =>  a ? b : c && d
    // In the first two cases we end up with nested hook expressions.
    // In the third, we need to special case the last condition.
    // So we start to build an expression from left to right.
    int pos = n;
    Expression e = expressionChildOf(condParts.get(--pos));
    if (!hasElse) {
        Expression lastCond = (Expression) condParts.get(--pos);
        if (Operation.is(lastCond, Operator.NOT)) {
            e = Operation.createInfix(Operator.LOGICAL_OR, (Expression) lastCond.children().get(0), e);
        } else {
            e = Operation.createInfix(Operator.LOGICAL_AND, lastCond, e);
        }
    }
    while (pos > 0) {
        Expression clause = expressionChildOf(condParts.get(--pos));
        Expression cond = (Expression) condParts.get(--pos);
        FilePosition fpos = FilePosition.span(cond.getFilePosition(), e.getFilePosition());
        if (clause instanceof BooleanLiteral && e instanceof BooleanLiteral) {
            BooleanLiteral a = (BooleanLiteral) clause, b = (BooleanLiteral) e;
            if (a.getValue() == b.getValue()) {
                e = commaOp(cond, a).fold(false);
            } else {
                // cond ? true : false -> !!cond
                int nNotsNeeded = a.getValue() ? 2 : 1;
                if (nNotsNeeded == 2 && "boolean".equals(cond.typeOf())) {
                    nNotsNeeded = 0;
                }
                e = cond;
                while (--nNotsNeeded >= 0) {
                    e = Operation.create(e.getFilePosition(), Operator.NOT, e).fold(false);
                }
            }
        } else if (Operation.is(cond, Operator.NOT)) {
            Expression notCond = ((Operation) cond).children().get(0);
            e = Operation.create(fpos, Operator.TERNARY, notCond, e, clause);
        } else {
            e = Operation.create(fpos, Operator.TERNARY, cond, clause, e);
        }
        e = optimizeExpressionFlow(e);
    }
    return (Statement) ParseTreeNodes.newNodeInstance(clauseClass, parentPos, null, Collections.singletonList(e));
}

15. ExpressionTest#assertSimplified()

Project: caja
Source File: ExpressionTest.java
View license
private void assertSimplified(String golden, String input) throws ParseException {
    Expression simple = jsExpr(fromString(input)).simplifyForSideEffect();
    if (golden == null) {
        assertNull(input, simple);
        return;
    }
    assertEquals(input, render(jsExpr(fromString(golden))), render(simple));
}

16. CajaTestCase#jsExpr()

Project: caja
Source File: CajaTestCase.java
View license
protected Expression jsExpr(CharProducer cp, boolean quasi) throws ParseException {
    JsLexer lexer = new JsLexer(cp);
    JsTokenQueue tq = new JsTokenQueue(lexer, sourceOf(cp), JsTokenQueue.NO_COMMENT);
    Parser p = new Parser(tq, mq, quasi);
    Expression e = p.parseExpression(true);
    tq.expectEmpty();
    return e;
}