Question

Here is the issue:

I have a class for e.g.,

public class EmployeeServiceImpl  {


@Autowired
EmployeeDAO empDAO;

public void findDepartments() throws NoEmployeeFoundException {

        int age = empDAO.findEmployeeById(12).getAge();

        if( age  > 30 ){
            //do something
        }else{
            //do something else.
        }

}
}

My goal is to :

(1) detect the variable assignment (2) remove the variable assignment and (3) add the assigned variable as method parameter.

So, after AST transformation, the code will look like :

public class EmployeeServiceImpl  {


@Autowired
EmployeeDAO empDAO;

public void findDepartments(int age) throws NoEmployeeFoundException {

        if( age  > 30 ){
            //do something
        }else{
            //do something else.
        }

}
}

I am able to do (1) & (2). However, for (3), although the variable assignment node is getting removed, I'm not able to add the parameter to the method. The AST transformer code is given below. What am I missing? (Please forgive the monolithic code and the absolute disregard for sound design)

    MethodVisitor visitor = new MethodVisitor();

            String source = unit.getSource();
            Document document = new Document(source);

            ASTParser parser = ASTParser.newParser(AST.JLS3);
            parser.setSource(unit);

            CompilationUnit astRoot = parse(unit);
            AST ast = astRoot.getAST();


            astRoot.accept(visitor);

            TestGenClassVisitor classVisitor = new TestGenClassVisitor();
            for (MethodDeclaration method : visitor.getMethods()) {
                method.accept( classVisitor );
            }


            // creation of ASTRewrite
            ASTRewrite rewrite = ASTRewrite.create( ast );

            astRoot.recordModifications();

            // for getting insertion position
            TypeDeclaration typeDecl = (TypeDeclaration) astRoot.types()
                    .get(0);
            MethodDeclaration methodDecl = typeDecl.getMethods()[0];
            Block block = methodDecl.getBody();

            List<VariableDeclarationStatement> varDeclarations = classVisitor.getReplaceableVardDeclarationNodes();
            ListRewrite listRewrite = rewrite.getListRewrite(block,
                    Block.STATEMENTS_PROPERTY);

            TextEditGroup textEditGroup = new TextEditGroup("abc");

            for( VariableDeclarationStatement statement : varDeclarations ){


                List<VariableDeclarationFragment> fragments = statement.fragments();

                for( VariableDeclarationFragment fragment : fragments){

                    IVariableBinding varBinding = fragment.resolveBinding();

                    System.out.println("Will replace node with var name :"+ varBinding.getName() +", of type :"+varBinding.getType().getQualifiedName());

                    SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
                    singleVariableDeclaration.setType(ast.newPrimitiveType(PrimitiveType.toCode(varBinding.getType().getQualifiedName())));
                    singleVariableDeclaration.setName(ast.newSimpleName(varBinding.getName()));
                    singleVariableDeclaration.setVarargs(false);
                    singleVariableDeclaration.setExtraDimensions(0);

                    methodDecl.parameters().add(singleVariableDeclaration);

                }

                listRewrite.remove(statement, textEditGroup);


            }


            TextEdit edits = rewrite.rewriteAST();

            // computation of the new source code
            try {
                edits.apply(document);
            } catch (MalformedTreeException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (BadLocationException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }


            String newSource = document.get();


            FileOutputStream fos = null;
            try {
                File newFile = File.createTempFile("Modified", ".java");

                fos = new FileOutputStream(newFile);
                fos.write(newSource.getBytes());
                fos.flush();

                System.out.println("File created at " + newFile.getCanonicalPath());

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally{
                try {
                    fos.close();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
Was it helpful?

Solution

The trick was to use ListRewrite properly. Solved it using the following code:

    ASTRewrite rewrite = ASTRewrite.create( ast );

            astRoot.recordModifications();

            // for getting insertion position
            TypeDeclaration typeDecl = (TypeDeclaration) astRoot.types()
                    .get(0);
            MethodDeclaration methodDecl = typeDecl.getMethods()[0];

            Block block = methodDecl.getBody();


            ListRewrite paramRewrite = rewrite.getListRewrite( methodDecl ,
                    MethodDeclaration.PARAMETERS_PROPERTY);


            ListRewrite listRewrite = rewrite.getListRewrite( block ,
                    Block.STATEMENTS_PROPERTY );

            List<SingleVariableDeclaration> paramList = new ArrayList<SingleVariableDeclaration>();

            List<VariableDeclarationStatement> varDeclarations =  classVisitor.getReplaceableVardDeclarationNodes();

            for( VariableDeclarationStatement statement : varDeclarations ){


                List<VariableDeclarationFragment> fragments = statement.fragments();

                for( VariableDeclarationFragment fragment : fragments){

                    IVariableBinding varBinding = fragment.resolveBinding();

                    System.out.println("Will replace node with var name :"+ varBinding.getName() +", of type :"+varBinding.getType().getQualifiedName());


                    SingleVariableDeclaration singleVariableDeclaration = ast.newSingleVariableDeclaration();
                    singleVariableDeclaration.setType(ast.newPrimitiveType(PrimitiveType.toCode(varBinding.getType().getQualifiedName())));
                    singleVariableDeclaration.setName(ast.newSimpleName(varBinding.getName()));

                    paramRewrite.insertLast( singleVariableDeclaration, null);


                }

                listRewrite.remove(statement, null);


            }


            TextEdit edits = rewrite.rewriteAST(document, null);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top