java - 从 JAVA 源 AST 中删除所有方法调用

标签 java eclipse abstract-syntax-tree eclipse-jdt

嗨,我找到了所有 MethodinvocationASTVisitor并将删除所有 ASTRewrite但是当对删除方法使用“for 循环”时,只删除调用事件中的第一个方法调用。我想问题原因不刷新 AST 、 CompiliationUnit 、 ICompilationUnit 或 ASTRewrite但我不知道何时以及如何刷新它以在第一个事件中全部删除。

static void createAST(ICompilationUnit unit) throws JavaModelException {
    // now create the AST for the ICompilationUnits
    CompilationUnit parse = parse(unit);
    MethodVisitor visitor = new MethodVisitor();
    parse.accept(visitor);
    for (MethodInvocation metInv : visitor.getMethods1()) {
        try {
            //if declarated by user. 
            if (metInv.resolveMethodBinding().getDeclaringClass().isFromSource()) {
                methodInvocRemove(unit, metInv);
            }
        
        } catch (Exception e) {
            System.out.println("EXCEPOTION:" + e.getMessage());
        }
    }
}

此方法用于删除所有 MethodInvocations。

private static void methodInvocRemove(ICompilationUnit unit, MethodInvocation met) {
    try {
        IProject project = unit.getJavaProject().getProject();
        CompilationUnit astRoot = parse(unit);
        // create a ASTRewrite
        AST ast = astRoot.getAST();
        ASTRewrite rewriter = ASTRewrite.create(met.getParent().getParent().getAST());
        rewriter.remove(met.getName().getParent(), null);
        TextEdit edits;
        edits = rewriter.rewriteAST();
        Document document = new Document(unit.getSource());
        edits.apply(document);
        // this is the code for adding statements
        unit.getBuffer().setContents(document.get());
        unit.getBuffer().close();
    } catch (MalformedTreeException e) {
        System.out.println("EXP!!!" + e.getMessage());
    } catch (BadLocationException e) {
        System.out.println("EXP!!!" + e.getMessage());
    } catch (JavaModelException e) {
        System.out.println("EXP!!!" + e.getMessage());
    } catch (IllegalArgumentException e) {
        System.out.println("EXP!!!" + e.getMessage());
    }
}

此方法用于使用 ASTVisitor 调用查找方法。在 Eclipse JDT 上的每个事件之后调用此方法。

public static void findMethod(IProject project) {
    try {
        if (project.isNatureEnabled("org.eclipse.jdt.core.javanature")) {
            IPackageFragment[] packages = JavaCore.create(project).getPackageFragments();
            for (IPackageFragment myPack : packages) {
                if (myPack.getKind() == IPackageFragmentRoot.K_SOURCE) {
                    for (ICompilationUnit unit : myPack.getCompilationUnits()) {
                        CompilationUnit parse = parse(unit);
                    }
                }
            }
        }
    } catch (CoreException e) {
        System.out.println("EXP!!!"+e.getMessage());
    }
}

用于解析和修改的Java文件示例代码。

public class MethodInvoc {

private void invoc1()
{
    MethodDeclar object1 = new MethodDeclar();
    System.out.println(object1.getStr());
}

private void invoc2() {
    MethodDeclar object2 = new MethodDeclar();
    System.out.println(object2.getStr());
}

private void invoc4()
{
    MethodDeclar object3 = new MethodDeclar();
    System.out.println(object3.getStr());
}
}

在调用事件并运行 methodInvocRemove 之后,上面的代码更改为:

 public class MethodInvoc {

private void invoc1()
{
    MethodDeclar object1 = new MethodDeclar();
    System.out.println();
}

private void invoc2() {
    MethodDeclar object2 = new MethodDeclar();
    System.out.println(object2.getStr());//not change this :( 
}

private void invoc4()
{
    MethodDeclar object3 = new MethodDeclar();
    System.out.println(object3.getStr());//not change this :( 
}
}

最佳答案

您需要为每个 CompilationUnit 缓存您的 ASTRewrite,使用 ASTRewrite.remove(...) 删除所有 MethodInvocation 节点 然后只应用所有编辑一次。

所以在伪代码中:

ASTRewrite rewriter = ASTRewrite.create(astRoot.getAST());
for (MethodInvocation metInv : getAllMethodInvocationsToRemove()) {
    rewriter.remove(metInv, null);
}
unit.applyTextEdit(rewriter.rewriteAST(), new NullProgressMonitor());

要在 rewriter 中应用编辑,我对这段代码(其中 unitICompilationUnit 的一个实例)有很好的经验,而不是使用文档:

unit.applyTextEdit(rewriter.rewriteAST(), new NullProgressMonitor());

您可能还想看看这篇文章,并使用 ICompilationUnit.becomeWorkingCopy 以及 ICompilationUnit.commitWorkingCopy 来包装您的更改:Eclipse AST not changing files which are not opened in eclipse

关于java - 从 JAVA 源 AST 中删除所有方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27498536/

相关文章:

eclipse - Apache Tomcat 8.0 无法加载使用 Eclipse for Java EE、Mars 2 用 Kotlin 编写的 servlet 类

parsing - ANTLR : Generate back source file from AST

java - 修复 Eclipse java 引用数据库损坏?

Eclipse 一直要求输入 svn 密码

c++ - 如何区分 Clang AST 访问者中的函数定义和函数声明

Python ast 包 : traversing object hierarchies

java - 可以跟踪我在字符串中的位置、空白并停止循环的方法

java - 审查将带有 Lambda 的 C++ for_each 移植到 Java

java - 如何将 Eclipse Kepler 设置应用到 Netbeans 8.0?

java - RMI实现Java