@Override public boolean enterIndexNode(final IndexNode indexNode) { enterDefault(indexNode); type("MemberExpression"); comma(); property("object"); indexNode.getBase().accept(this); comma(); property("property"); indexNode.getIndex().accept(this); comma(); property("computed", true); return leave(); }
private boolean checkValidLValue(final Expression init, final String contextString) { if (init instanceof IdentNode) { if (!checkIdentLValue((IdentNode)init)) { return false; } verifyIdent((IdentNode)init, contextString); return true; } else if (init instanceof AccessNode || init instanceof IndexNode) { return true; } else if (isDestructuringLhs(init)) { verifyDestructuringAssignmentPattern(init, contextString); return true; } else { return false; } }
@Override public Node leaveIndexNode(final IndexNode indexNode) { final String name = getConstantPropertyName(indexNode.getIndex()); if (name != null) { // If index node is a constant property name convert index node to access node. assert Token.descType(indexNode.getToken()) == TokenType.LBRACKET; return new AccessNode(indexNode.getToken(), indexNode.getFinish(), indexNode.getBase(), name); } return super.leaveIndexNode(indexNode); }
@Override public boolean enterIndexNode(final IndexNode indexNode) { curExpr = new ArrayAccessTreeImpl(indexNode, translateExpr(indexNode.getBase()), translateExpr(indexNode.getIndex())); return false; }
@Override public Node leaveIndexNode(final IndexNode indexNode) { final String name = getConstantPropertyName(indexNode.getIndex()); if (name != null) { // If index node is a constant property name convert index node to access node. assert indexNode.isIndex(); return new AccessNode(indexNode.getToken(), indexNode.getFinish(), indexNode.getBase(), name); } return super.leaveIndexNode(indexNode); }
/** * Verify an assignment expression. * @param op Operation token. * @param lhs Left hand side expression. * @param rhs Right hand side expression. * @return Verified expression. */ private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) { final TokenType opType = Token.descType(op); switch (opType) { case ASSIGN: case ASSIGN_ADD: case ASSIGN_BIT_AND: case ASSIGN_BIT_OR: case ASSIGN_BIT_XOR: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_MUL: case ASSIGN_SAR: case ASSIGN_SHL: case ASSIGN_SHR: case ASSIGN_SUB: if (!(lhs instanceof AccessNode || lhs instanceof IndexNode || lhs instanceof IdentNode)) { return referenceError(lhs, rhs, env._early_lvalue_error); } if (lhs instanceof IdentNode) { if (!checkIdentLValue((IdentNode)lhs)) { return referenceError(lhs, rhs, false); } verifyStrictIdent((IdentNode)lhs, "assignment"); } break; default: break; } // Build up node. return new BinaryNode(op, lhs, rhs); }
/** * A symbol (and {@link jdk.nashorn.internal.runtime.Property}) can be tagged as "may be primitive". * This is used a hint for dual fields that it is even worth it to try representing this * field as something other than java.lang.Object. * * @param node node in which to tag symbols as primitive * @param to which primitive type to use for tagging */ private static void setCanBePrimitive(final Node node, final Type to) { final HashSet<Node> exclude = new HashSet<>(); node.accept(new NodeVisitor<LexicalContext>(new LexicalContext()) { private void setCanBePrimitive(final Symbol symbol) { LOG.info("*** can be primitive symbol ", symbol, " ", Debug.id(symbol)); symbol.setCanBePrimitive(to); } @Override public boolean enterIdentNode(final IdentNode identNode) { if (!exclude.contains(identNode)) { setCanBePrimitive(identNode.getSymbol()); } return false; } @Override public boolean enterAccessNode(final AccessNode accessNode) { setCanBePrimitive(accessNode.getProperty().getSymbol()); return false; } @Override public boolean enterIndexNode(final IndexNode indexNode) { exclude.add(indexNode.getBase()); //prevent array base node to be flagged as primitive, but k in a[k++] is fine return true; } }); }
/** * Verify an assignment expression. * @param op Operation token. * @param lhs Left hand side expression. * @param rhs Right hand side expression. * @return Verified expression. */ private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) { final TokenType opType = Token.descType(op); switch (opType) { case ASSIGN: case ASSIGN_ADD: case ASSIGN_BIT_AND: case ASSIGN_BIT_OR: case ASSIGN_BIT_XOR: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_MUL: case ASSIGN_SAR: case ASSIGN_SHL: case ASSIGN_SHR: case ASSIGN_SUB: if (!(lhs instanceof AccessNode || lhs instanceof IndexNode || lhs instanceof IdentNode)) { return referenceError(lhs, rhs, env._early_lvalue_error); } if (lhs instanceof IdentNode) { if (!checkIdentLValue((IdentNode)lhs)) { return referenceError(lhs, rhs, false); } verifyStrictIdent((IdentNode)lhs, "assignment"); } break; default: break; } // Build up node. if(BinaryNode.isLogical(opType)) { return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs)); } return new BinaryNode(op, lhs, rhs); }
@Override public Node leaveIndexNode(final IndexNode indexNode) { return setProgramPoint(indexNode); }
@Override public boolean enterIndexNode(final IndexNode indexNode) { tagNeverOptimistic(indexNode.getBase()); return true; }
private static int getOptimisticIgnoreCountForSelfModifyingExpression(final Expression target) { return target instanceof AccessNode ? 1 : target instanceof IndexNode ? 2 : 0; }
@Override public Node leaveIndexNode(final IndexNode indexNode) { weight += ACCESS_WEIGHT; return indexNode; }
/** * Verify an assignment expression. * @param op Operation token. * @param lhs Left hand side expression. * @param rhs Right hand side expression. * @return Verified expression. */ private Expression verifyAssignment(final long op, final Expression lhs, final Expression rhs) { final TokenType opType = Token.descType(op); switch (opType) { case ASSIGN: case ASSIGN_ADD: case ASSIGN_BIT_AND: case ASSIGN_BIT_OR: case ASSIGN_BIT_XOR: case ASSIGN_DIV: case ASSIGN_MOD: case ASSIGN_MUL: case ASSIGN_SAR: case ASSIGN_SHL: case ASSIGN_SHR: case ASSIGN_SUB: if (lhs instanceof IdentNode) { if (!checkIdentLValue((IdentNode)lhs)) { return referenceError(lhs, rhs, false); } verifyIdent((IdentNode)lhs, "assignment"); break; } else if (lhs instanceof AccessNode || lhs instanceof IndexNode) { break; } else if (opType == ASSIGN && isDestructuringLhs(lhs)) { verifyDestructuringAssignmentPattern(lhs, "assignment"); break; } else { return referenceError(lhs, rhs, env._early_lvalue_error); } default: break; } // Build up node. if(BinaryNode.isLogical(opType)) { return new BinaryNode(op, new JoinPredecessorExpression(lhs), new JoinPredecessorExpression(rhs)); } return new BinaryNode(op, lhs, rhs); }
@Override public boolean enterIndexNode(final IndexNode indexNode) { visitExpression(indexNode.getBase()); visitExpression(indexNode.getIndex()); return pushExpressionType(indexNode); }