private void visitAssignmentAtRoot(final Assignment node) { if (node.getRight() instanceof FunctionNode || ingoreAbstractMethod(node)) { if (node.getParent() instanceof ExpressionStatement) { try { visitMethodOrClass(((PropertyGet) node.getLeft()).toSource(), node.getJsDoc()); if (node.getRight() instanceof PropertyGet) { LOG.info("left:{}, right:{}", ((PropertyGet) node.getLeft()).toSource(), ((PropertyGet) node.getRight()).toSource()); } } catch (final ClassCastException e) { LOG.error("Node different then expected in file:{},", fileName, e); } } else { // LOG.debug("Node at linenr {} ignored in file:{}", // node.getLineno(), fileName); } } else if (node.getParent() instanceof ExpressionStatement) { visitMethodOrEnum(((PropertyGet) node.getLeft()).toSource(), node.getJsDoc(), node.getRight()); } }
private void visitOtherNode(final AstNode node) { if (node instanceof PropertyGet && node.getParent() instanceof ExpressionStatement) { if (node.getJsDoc() == null) { LOG.error("Node {} has empty comment in file:{}", node.toSource(), fileName); return; } final JsElement element = parser.parse(fileName, node.getJsDoc()); final String typedef = node.toSource(); if (isMethod(typedef, element)) { addMethodOrField(typedef, element, false); } else if (element.getType() == null) { final JsFile jFile = parseClassOrInterfaceName(typedef, element.isInterface(), element); files.put(typedef, jFile); } else { LOG.error("Type '{}' ignored in file:{}", typedef, fileName); } } }
private String getDirective(AstNode n) { if (n instanceof ExpressionStatement) { AstNode e = ((ExpressionStatement) n).getExpression(); if (e instanceof StringLiteral) { return ((StringLiteral) e).getValue(); } } return null; }
private AstNode defaultXmlNamespace() throws IOException { if (currentToken != Token.DEFAULT) codeBug(); consumeToken(); mustHaveXML(); setRequiresActivation(); int lineno = ts.lineno, pos = ts.tokenBeg; if (!(matchToken(Token.NAME) && "xml".equals(ts.getString()))) { reportError("msg.bad.namespace"); } if (!(matchToken(Token.NAME) && "namespace".equals(ts.getString()))) { reportError("msg.bad.namespace"); } if (!matchToken(Token.ASSIGN)) { reportError("msg.bad.namespace"); } AstNode e = expr(); UnaryExpression dxmln = new UnaryExpression(pos, getNodeEnd(e) - pos); dxmln.setOperator(Token.DEFAULTNAMESPACE); dxmln.setOperand(e); dxmln.setLineno(lineno); ExpressionStatement es = new ExpressionStatement(dxmln, true); return es; }
private static AstNode getExpression(MethodReference method, AstNode statement) { if (method.getReturnType() == ValueType.VOID) { if (statement instanceof ExpressionStatement) { return ((ExpressionStatement) statement).getExpression(); } else if (statement instanceof ThrowStatement) { return ((ThrowStatement) statement).getExpression(); } } else { if (statement instanceof ReturnStatement) { return ((ReturnStatement) statement).getReturnValue(); } } return null; }
@Override public boolean visit(AstNode node) { if (node==null) { return false; } int nodeType = node.getType(); switch (nodeType) { case Token.SCRIPT: // AstRoot curScopeTreeNode = root; return true; case Token.FUNCTION: FunctionNode fn = (FunctionNode)node; return visitFunction(fn); case Token.VAR: VariableDeclaration varDec = (VariableDeclaration)node; return visitVariableDeclaration(varDec); case Token.BLOCK: return true; case Token.EXPR_RESULT: ExpressionStatement exprStmt = (ExpressionStatement)node; return visitExpressionStatement(exprStmt); } return false; // Unhandled node type }
private void processExpressionStatement(Node child, CodeBlock block, Set<Completion> set, String entered, int offset) { ExpressionStatement exp = (ExpressionStatement) child; AstNode expNode = exp.getExpression(); iterateNode(expNode, set, entered, block, offset); }
/** * Extract completions from expression node */ private void processExpressionNode(Node child, CodeBlock block, Set<Completion> set, String entered, int offset) { if (child instanceof ExpressionStatement) { ExpressionStatement expr = (ExpressionStatement) child; iterateNode(expr.getExpression(), set, entered, block, offset); } }
/** * Test node to check whether to ignore resolving, this is for * parameters * * @param node node to test * @return true to ignore */ private boolean ignore(AstNode node, boolean ignoreParams) { switch (node.getType()) { // ignore errors e.g if statement - if(a. //no closing brace case Token.EXPR_VOID: case Token.EXPR_RESULT: return ((ExpressionStatement) node).getExpression() .getType() == Token.ERROR; case Token.ERROR: case Token.GETPROP: case Token.SCRIPT: return true; default: { if (isParameter(node)) { collectAllNodes(node); // everything within this node // is a parameter return ignoreParams; } break; } } //if (JavaScriptHelper.isInfixOnly(node)) // return true; return false; }
private Node transformExprStmt(ExpressionStatement node) { Node expr = transform(node.getExpression()); decompiler.addEOL(Token.SEMI); return new Node(node.getType(), expr, node.getLineno()); }
private AstNode let(boolean isStatement, int pos) throws IOException { LetNode pn = new LetNode(pos); pn.setLineno(ts.lineno); if (mustMatchToken(Token.LP, "msg.no.paren.after.let")) pn.setLp(ts.tokenBeg - pos); pushScope(pn); try { VariableDeclaration vars = variables(Token.LET, ts.tokenBeg, isStatement); pn.setVariables(vars); if (mustMatchToken(Token.RP, "msg.no.paren.let")) { pn.setRp(ts.tokenBeg - pos); } if (isStatement && peekToken() == Token.LC) { // let statement consumeToken(); int beg = ts.tokenBeg; // position stmt at LC AstNode stmt = statements(); mustMatchToken(Token.RC, "msg.no.curly.let"); stmt.setLength(ts.tokenEnd - beg); pn.setLength(ts.tokenEnd - pos); pn.setBody(stmt); pn.setType(Token.LET); } else { // let expression AstNode expr = expr(); pn.setLength(getNodeEnd(expr) - pos); pn.setBody(expr); if (isStatement) { // let expression in statement context ExpressionStatement es = new ExpressionStatement(pn, !insideFunction()); es.setLineno(pn.getLineno()); return es; } } } finally { popScope(); } return pn; }
/** * For a {@link FunctionNode} representing a constructor, if the constructor C is * followed by a sequence of assignments of the form C.prototype.a = ...;, return * a set of all the properties written on the prototype. If the assignments do not * fit that form, return the empty set. * @param consNode * @return */ public static Set<String> getWrittenPrototypeProps(FunctionNode consNode) { Set<String> result = HashSetFactory.make(); AstNode parent = consNode.getParent(); boolean found = false; for (Node child: parent) { if (child instanceof EmptyStatement) { continue; } if (child.equals(consNode)) { found = true; } else if (found) { // looking for a statement of the form C.prototype.a = ...; boolean foundAssign = false; if (child instanceof ExpressionStatement) { AstNode expression = ((ExpressionStatement)child).getExpression(); if (expression instanceof Assignment) { Assignment assign = (Assignment) expression; AstNode lhs = assign.getLeft(); if (lhs instanceof PropertyGet) { PropertyGet pg = (PropertyGet) lhs; AstNode pgTarget = pg.getTarget(); if (pgTarget instanceof PropertyGet) { PropertyGet basePG = (PropertyGet) pgTarget; if (basePG.getProperty().getIdentifier().equals("prototype")) { // BINGO result.add(pg.getProperty().getIdentifier()); foundAssign = true; } } } } } if (!foundAssign) { // stop looking for more assignments break; } } } return result; }
/** * This method generates constraints for all relevant AstNodes. It delegates its work to various * processXXX() methods that handle AstNodes of type XXX. */ @Override public boolean visit(AstNode node) { if (node instanceof VariableInitializer){ processVariableInitializer(node); } else if (node instanceof ReturnStatement){ processReturnStatement((ReturnStatement)node); } else if (node instanceof ExpressionStatement){ processExpressionStatement((ExpressionStatement)node); } else if (node instanceof ForLoop){ processForLoop((ForLoop)node); } else if (node instanceof ForInLoop){ processForInLoop((ForInLoop)node); }else if (node instanceof WhileLoop){ processWhileLoop((WhileLoop)node); } else if (node instanceof DoLoop){ processDoLoop((DoLoop)node); } else if (node instanceof NewExpression){ processNewExpression((NewExpression)node); } else if (node instanceof FunctionCall){ processFunctionCall((FunctionCall)node); } else if (node instanceof ElementGet){ processElementGet((ElementGet)node); } else if (node instanceof FunctionNode){ processFunctionNode((FunctionNode)node); } else if (node instanceof IfStatement){ processIfStatement((IfStatement)node); } else if (node instanceof KeywordLiteral){ processKeywordLiteral((KeywordLiteral)node); } else if (node instanceof SwitchStatement){ processSwitchStatement((SwitchStatement)node); } else if (node instanceof SwitchCase){ processSwitchCase((SwitchCase)node); } else if ((node instanceof AstRoot) || //AstRoot: no constraints need to be generated (node instanceof BreakStatement) || //BreakStatement: no constraints need to be generated (node instanceof VariableDeclaration) || //VariableDeclaration: we generate constraints for its constituent VariableInitializer nodes (node instanceof Name) || //Name: generate constraints for complex expressions that refer to names (node instanceof NumberLiteral) || //NumberLiteral: generate constraints for complex expressions that refer to names (node instanceof StringLiteral) || //StringLiteral: generate constraints for complex expressions that refer to names (node instanceof Assignment) || // Assignment is a special case of InfixExpression (node instanceof ArrayLiteral) || (node instanceof UnaryExpression) || (node instanceof InfixExpression) || (node instanceof ConditionalExpression) || (node instanceof ParenthesizedExpression) || (node instanceof EmptyExpression) || (node instanceof ObjectLiteral) || (node instanceof EmptyStatement) || (node instanceof ContinueStatement) || (node instanceof Scope) || (node instanceof Block)){ // // occurs in programs with for loops -- nothing to be done here? /* nothing */ } else { error("unsupported node " + node.toSource().trim() + " of type: " + node.getClass().getName(), node); } return true; }
/** * generate constraints for expression statements. */ private void processExpressionStatement(ExpressionStatement node) throws Error { processExpression(node.getExpression()); }
/** * assignment to the "prototype" property */ private void processAssignToPrototype(Assignment a, AstNode left, AstNode right, ITypeTerm expTerm) throws Error { PropertyGet pg = (PropertyGet)left; AstNode base = pg.getTarget(); ITypeTerm pgTerm = findOrCreateExpressionTerm(pg); if (base instanceof Name){ Name name = (Name)base; if (!validRHSForAssignToPrototype(right)) { error( "expression " + right.toSource() + " cannot be assigned to a constructor prototype (line " + right.getLineno() + ")", a); } // can only write to prototype immediately after declaration of // constructor of the same name AstNode parent = a.getParent(); if (!(parent instanceof ExpressionStatement)) { error( "assignment to prototype property not allowed here (line " + a.getLineno() + ")", a); return; } Node prev = getPredecessorNode(parent); if (!(prev instanceof FunctionNode)) { error( "assignment to prototype property only allowed after constructor declaration (line " + a.getLineno() + ")", a); return; } FunctionNode fn = (FunctionNode) prev; String functionName = fn.getName(); String identifier = name.getIdentifier(); if (!functionName.equals(identifier)) { error( "can only assign to prototype of function " + functionName + " here (line " + a.getLineno() + ")", a); return; } ITypeTerm baseTerm = findOrCreateExpressionTerm(base); // make term for expression ITypeTerm nameTerm = findOrCreateNameDeclarationTerm(name); // find unique representative for referenced Name addTypeEqualityConstraint(baseTerm, nameTerm, a.getLineno(), null); // equate them ITypeTerm protoTerm = findOrCreateProtoTerm(baseTerm, pg.getLineno()); ITypeTerm rightTerm = processExpression(right); addTypeEqualityConstraint(pgTerm, protoTerm, a.getLineno(), null); addTypeEqualityConstraint(rightTerm, protoTerm, a.getLineno(), null); addTypeEqualityConstraint(expTerm, protoTerm, a.getLineno(), null); } else { error("processAssignToPrototype: unsupported case for receiver expression: " + base.getClass().getName(), base); } }
private void checkForValidProtoPropAssign(Assignment a, PropertyGet pg, int assignLineNo, PropertyGet basePG) { AstNode baseTarget = basePG.getTarget(); if (!(baseTarget instanceof Name)) { error("assignment to property of prototype not valid (line " + assignLineNo + ")", a); return; } Name baseName = (Name) baseTarget; AstNode parent = a.getParent(); if (!(parent instanceof ExpressionStatement)) { error("assignment to property of prototype not valid (line " + assignLineNo + ")", a); return; } Node prev = getPredecessorNode(parent); if (prev instanceof FunctionNode) { FunctionNode fn = (FunctionNode) prev; String functionName = fn.getName(); String identifier = baseName.getIdentifier(); if (!functionName.equals(identifier)) { error("can only assign to prototype of function " + functionName + " here (line " + assignLineNo + ")", a); return; } } else if (prev instanceof ExpressionStatement) { // it needs to be an assignment either to C.prototype or C.prototype.foo // TODO clean up this gross code AstNode expression = ((ExpressionStatement)prev).getExpression(); if (!(expression instanceof Assignment)) { error("assignment to property of prototype not valid (line " + assignLineNo + ")", a); return; } Assignment prevAssign = (Assignment) expression; AstNode prevLeft = prevAssign.getLeft(); if (!(prevLeft instanceof PropertyGet)) { error("assignment to property of prototype not valid (line " + assignLineNo + ")", a); return; } PropertyGet prevPG = (PropertyGet) prevLeft; AstNode prevPGTarget = prevPG.getTarget(); if (prevPG.getProperty().getIdentifier().equals("prototype")) { checkForSameName(assignLineNo, baseName, prevPGTarget); } else if (prevPGTarget instanceof PropertyGet) { PropertyGet prevPGBasePG = (PropertyGet) prevPGTarget; if (!prevPGBasePG.getProperty().getIdentifier().equals("prototype")) { error("assignment to property of prototype not valid (line " + assignLineNo + ")", a); return; } checkForSameName(assignLineNo, baseName, prevPGBasePG.getTarget()); } else { error("assignment to property of prototype not valid (line " + assignLineNo + ")", a); return; } } else { error("assignment to property of prototype not valid (line " + assignLineNo + ")", a); return; } }
private void print(ExpressionStatement node) throws IOException { print(node.getExpression()); writer.append(';'); }