使用Eclipse AST添加方法参数

时间:2014-04-10 08:37:34

标签: java eclipse eclipse-jdt

问题在于:

我有一个班级,例如,

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.
        }

}
}

我的目标是:

(1)检测变量赋值 (2)删除变量赋值和 (3)将赋值的变量添加为方法参数。

因此,在AST转换之后,代码将如下所示:

public class EmployeeServiceImpl  {


@Autowired
EmployeeDAO empDAO;

public void findDepartments(int age) throws NoEmployeeFoundException {

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

}
}

我能做(1)& (2)。但是,对于(3),虽然变量赋值节点被删除,但我无法将参数添加到方法中。 AST变换器代码如下。我错过了什么? (请原谅单片代码和绝对无视声音设计)

    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();
                }
            }

1 个答案:

答案 0 :(得分:0)

诀窍是正确使用ListRewrite。 使用以下代码解决了它:

    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);