/** * Builds a new {@link MethodInvocation} instance. * * @param expression the method invocation expression * @param methodName the name of the invoked method * @param arguments the arguments for the method invocation * @return a new method invocation */ public MethodInvocation invoke(String expression, String methodName, Expression... arguments) { final MethodInvocation mi = ast.newMethodInvocation(); mi.setExpression(ast.newSimpleName(expression)); mi.setName(ast.newSimpleName(methodName)); addAll(arguments(mi), arguments); return mi; }
@SuppressWarnings("unchecked") public MethodInvocation newCall(Expression obj, String funName, Expression... args) { MethodInvocation call = ast.newMethodInvocation(); call.setExpression(obj); call.setName(ast.newSimpleName(funName)); call.arguments().addAll(Arrays.asList(args)); return call; }
/** * Builds a new {@link MethodInvocation} instance. * * @param <E> the arguments type * @param expression the method invocation expression * @param methodName the name of the invoked method * @param arguments the arguments for the method invocation * @return a new method invocation */ public <E extends Expression> MethodInvocation invoke( Expression expression, String methodName, List<E> arguments) { final MethodInvocation mi = ast.newMethodInvocation(); mi.setExpression(expression); mi.setName(ast.newSimpleName(methodName)); addAll(arguments, mi); return mi; }
/** * create the update code block with dao invoked. * * @param ast the ast tree. fc the configuration. */ @SuppressWarnings("unchecked") public Block createBlock(AST ast, FastIbatisConfig fc) { Block block = ast.newBlock(); MethodInvocation methodInvocation = ast.newMethodInvocation(); methodInvocation.setExpression(ast.newName(Utils.lowFirstChar(fc.getModelName()) + "DAO")); methodInvocation.setName(ast.newSimpleName(fc.getMethodName())); methodInvocation.arguments().add(ast.newSimpleName("param")); ReturnStatement rs = ast.newReturnStatement(); rs.setExpression(methodInvocation); block.statements().add(rs); return block; }
private Delta deduplicate(CompilationUnit root, ASTRewrite rewrite, Cause cause) { final List<ASTNode> nodes = cause.getAffectedNodes(); final int size = nodes.size(); final int cloneNumber = size == 0 ? size : size - 1; // minus the original declaration if (cloneNumber == 0) { throw new RuntimeException("calling deduplicate() when there are no detected clones"); } else if (cloneNumber >= 1) { // NOTE: THIS WORKS ONLY AT METHOD LEVEL, other forms of duplication will // will be ignored. // The strategy this code follows to perform deduplication is the following: // per duplicated method declaration, find all of its invocations. Then // rename each found invocation using the name of the original method declaration. // After that, remove the duplicated method declaration. if (AstUtil.isOfType(MethodDeclaration.class, nodes.get(0))) { final MethodDeclaration original = AstUtil.exactCast(MethodDeclaration.class, nodes.get(0)); final Iterable<ASTNode> rest = Iterables.skip(nodes, 1); for (ASTNode eachClone : rest) { final MethodDeclaration duplicate = AstUtil.exactCast(MethodDeclaration.class, eachClone); final MethodDeclaration copied = AstUtil.copySubtree(MethodDeclaration.class, root.getAST(), duplicate); final boolean sameReturn = sameReturnType(original, copied); if (!sameReturn) { // all or none. We don't do partial deduplication throw new RuntimeException( "automatic deduplication cannot be done on methods " + "with different return types; please consider " + "manual deduplication."); } final MethodInvocationVisitor invokesOfDuplication = new MethodInvocationVisitor(copied.getName()); root.accept(invokesOfDuplication); final Set<MethodInvocation> invokes = invokesOfDuplication.getMethodInvocations(); for (MethodInvocation each : invokes) { final MethodInvocation copiedInvoke = AstUtil.copySubtree(MethodInvocation.class, root.getAST(), each); copiedInvoke.setName(root.getAST().newSimpleName(original.getName().getIdentifier())); rewrite.replace(each, copiedInvoke, null); } rewrite.remove(duplicate, null); } } } return createDelta(root, rewrite); }
public void testASTRewriteExample() throws Exception { // create a new project IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("Test"); project.create(null); project.open(null); try { // set the Java nature and Java build path IProjectDescription description = project.getDescription(); description.setNatureIds(new String[] {JavaCore.NATURE_ID}); project.setDescription(description, null); IJavaProject javaProject = JavaCore.create(project); // build path is: project as source folder and JRE container IClasspathEntry[] cpentry = new IClasspathEntry[] { JavaCore.newSourceEntry(javaProject.getPath()), JavaRuntime.getDefaultJREContainerEntry() }; javaProject.setRawClasspath(cpentry, javaProject.getPath(), null); Map<String, String> options = new HashMap<>(); options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE); options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4"); javaProject.setOptions(options); // create a test file IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(project); IPackageFragment pack1 = root.createPackageFragment("test1", false, null); StringBuffer buf = new StringBuffer(); buf.append("package test1;\n"); buf.append("public class E {\n"); buf.append(" public void foo(int i) {\n"); buf.append(" while (--i > 0) {\n"); buf.append(" System.beep();\n"); buf.append(" }\n"); buf.append(" }\n"); buf.append("}\n"); ICompilationUnit cu = pack1.createCompilationUnit("E.java", buf.toString(), false, null); // create an AST ASTParser parser = ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL); parser.setSource(cu); parser.setResolveBindings(false); CompilationUnit astRoot = (CompilationUnit) parser.createAST(null); AST ast = astRoot.getAST(); // create the descriptive ast rewriter ASTRewrite rewrite = ASTRewrite.create(ast); // get the block node that contains the statements in the method body TypeDeclaration typeDecl = (TypeDeclaration) astRoot.types().get(0); MethodDeclaration methodDecl = typeDecl.getMethods()[0]; Block block = methodDecl.getBody(); // create new statements to insert MethodInvocation newInv1 = ast.newMethodInvocation(); newInv1.setName(ast.newSimpleName("bar1")); Statement newStatement1 = ast.newExpressionStatement(newInv1); MethodInvocation newInv2 = ast.newMethodInvocation(); newInv2.setName(ast.newSimpleName("bar2")); Statement newStatement2 = ast.newExpressionStatement(newInv2); // describe that the first node is inserted as first statement in block, the other one as last // statement // note: AST is not modified by this ListRewrite listRewrite = rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY); listRewrite.insertFirst(newStatement1, null); listRewrite.insertLast(newStatement2, null); // evaluate the text edits corresponding to the described changes. AST and CU still // unmodified. TextEdit res = rewrite.rewriteAST(); // apply the text edits to the compilation unit Document document = new Document(cu.getSource()); res.apply(document); cu.getBuffer().setContents(document.get()); // test result String preview = cu.getSource(); buf = new StringBuffer(); buf.append("package test1;\n"); buf.append("public class E {\n"); buf.append(" public void foo(int i) {\n"); buf.append(" bar1();\n"); buf.append(" while (--i > 0) {\n"); buf.append(" System.beep();\n"); buf.append(" }\n"); buf.append(" bar2();\n"); buf.append(" }\n"); buf.append("}\n"); assertEquals(preview, buf.toString()); } finally { project.delete(true, null); } }