有没有办法使用Eclipse JDT将测试代码转换为MethodDeclaration?

时间:2014-03-24 06:53:47

标签: java eclipse-jdt

假设我已经从Java文件解析了CompilationUnit单元。现在,我想为Java文件添加一些新的复杂方法。使用简单的方法,如

public static void main(String[] args) {
    System.out.println("Hello" + " world");
}

我们可以手动编程为例:http://publib.boulder.ibm.com/infocenter/rsmhelp/v7r0m0/index.jsp?topic=/org.eclipse.jdt.doc.isv/guide/jdt_api_manip.htm

然而,使用复杂的方法,似乎是不可能的。我认为另一种解决方案是:将整个方法存储到String中,然后解析它并将结果添加到现有编译单元。

有没有办法将测试代码转换为MethodDeclaration,然后使用eclipse JDT追加到现有的编译单元?

1 个答案:

答案 0 :(得分:1)

我在此假设您在CompilationUnit包中说MethodDeclarationorg.eclipse.jdt.core.dom

  

然而,使用复杂的方法,似乎是不可能的。

实际上,您可以理论上使用org.eclipse.jdt.core.dom API创建任何可能的合法Java代码,方法是使用各种ASTNodes创建和链接相应的AST#new-methods。< / p>

对于复杂代码,使用ASTParser解析现有语句更方便。为此,您必须首先将解析器的源设置为语句的代码,然后将解析器类型设置为ASTParser.K_STATEMENTS。然后,在通过调用ASTParser#createAST创建ASTNode时,返回的节点将是Block类型。在将此块设置为例如MethodDeclaration的阻止,您必须通过调用AST将该块复制到现有ASTNode.copySubtree(ast, block)

这是一个完整的例子,展示了如何做到这一点:

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.Block;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.TypeDeclaration;

public class JdtDomExample {

    public static void main(String[] args) {

        // (1) somehow get an org.eclipse.jdt.core.dom.CompilationUnit, a TypeDeclaration, and a MethodDeclaration
        AST ast = AST.newAST(AST.JLS8);
        CompilationUnit cu =  ast.newCompilationUnit();
        TypeDeclaration typeDecl = ast.newTypeDeclaration();
        typeDecl.setName(ast.newSimpleName("MyClass"));
        cu.types().add(typeDecl);
        MethodDeclaration method = cu.getAST().newMethodDeclaration();
        method.setName(ast.newSimpleName("myMethod"));
        typeDecl.bodyDeclarations().add(method);

        // (2) create an ASTParser and parse the method body as ASTParser.K_STATEMENTS
        ASTParser parser = ASTParser.newParser(AST.JLS8);
        parser.setSource("System.out.println(\"Hello\" + \" world\");".toCharArray());
        parser.setKind(ASTParser.K_STATEMENTS);
        Block block = (Block) parser.createAST(null);

        // (3) copy the statements to the existing AST
        block = (Block) ASTNode.copySubtree(ast, block);
        method.setBody(block);

        // show the result
        System.out.println(cu);
    }
}

输出:

class MyClass {
  void myMethod(){
    System.out.println("Hello" + " world");
  }
}