使用Eclipse AST添加方法参数



问题如下:

我有一门课,例如

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

诀窍是正确使用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);

最新更新