public void testLinenoSwitch() { AstRoot root = parse( "\nswitch (a) {\n" + " case\n" + " 1:\n" + " b++;\n" + " case 2:\n" + " default:\n" + " b--;\n" + " }\n"); SwitchStatement switchStmt = (SwitchStatement) root.getFirstChild(); AstNode switchVar = switchStmt.getExpression(); List<SwitchCase> cases = switchStmt.getCases(); SwitchCase firstCase = cases.get(0); AstNode caseArg = firstCase.getExpression(); List<AstNode> caseBody = firstCase.getStatements(); ExpressionStatement exprStmt = (ExpressionStatement) caseBody.get(0); UnaryExpression incrExpr = (UnaryExpression) exprStmt.getExpression(); AstNode incrVar = incrExpr.getOperand(); SwitchCase secondCase = cases.get(1); AstNode defaultCase = cases.get(2); AstNode returnStmt = (AstNode) switchStmt.getNext(); assertEquals(1, switchStmt.getLineno()); assertEquals(1, switchVar.getLineno()); assertEquals(2, firstCase.getLineno()); assertEquals(3, caseArg.getLineno()); assertEquals(4, exprStmt.getLineno()); assertEquals(4, incrExpr.getLineno()); assertEquals(4, incrVar.getLineno()); assertEquals(5, secondCase.getLineno()); assertEquals(6, defaultCase.getLineno()); }
/** * Actual visiting method. * * @param node The node that is currently visited. * @return Whether to visit the children. */ @Override public boolean visit(AstNode node) { if (node instanceof FunctionNode) { FunctionNode func = (FunctionNode) node; String functionName = getFunctionName(func); if (functionName.equals(funcName)) { Node domNode = nodeProp.getNode(); String xpath = domNode.xpath; String line = nodeProp.getLine(); String value = nodeProp.getValue(); String typeofAccess = nodeProp.getTypeOfAccess(); String property = nodeProp.getProperty(); AstNode newNode = createMutationNode( func, xpath, ProgramPoint.ENTERPOSTFIX, typeofAccess, property, shouldDeleteNode); func.getBody().addChildToFront(newNode); /* get last line of the function */ AstNode lastnode = (AstNode) func.getBody().getLastChild(); /* if this is not a return statement, we need to add logging here also */ if (!(lastnode instanceof ReturnStatement)) { newNode = createMutationNode( func, xpath, ProgramPoint.EXITPOSTFIX, typeofAccess, property, shouldDeleteNode); /* add as last statement */ func.getBody().addChildToBack(newNode); } } } else if (node instanceof SwitchCase) { // Add block around all statements in the switch case SwitchCase sc = (SwitchCase) node; List<AstNode> statements = sc.getStatements(); List<AstNode> blockStatement = new ArrayList<AstNode>(); Block b = new Block(); if (statements != null) { Iterator<AstNode> it = statements.iterator(); while (it.hasNext()) { AstNode stmnt = it.next(); b.addChild(stmnt); } blockStatement.add(b); sc.setStatements(blockStatement); } } else if (node instanceof ReturnStatement) { FunctionNode func = node.getEnclosingFunction(); String functionName = getFunctionName(func); if (functionName.equals(funcName)) { Node domNode = nodeProp.getNode(); String xpath = domNode.xpath; String line = nodeProp.getLine(); String value = nodeProp.getValue(); String typeofAccess = nodeProp.getTypeOfAccess(); String property = nodeProp.getProperty(); AstNode newNode = createMutationNode( func, xpath, ProgramPoint.EXITPOSTFIX, typeofAccess, property, shouldDeleteNode); AstNode parent = makeSureBlockExistsAround(node); /* the parent is something we can prepend to */ parent.addChildBefore(newNode, node); } } return true; }