AST解析:在匿名方法中无法识别Catch子句

时间:2014-10-15 14:42:47

标签: java abstract-syntax-tree

我有以下代码:

public class TestClass2 {

    public void test() {

        new Button().addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

                try {

                } catch (Exception e1) {

                } 

            }
        });

        try {

        } catch (Exception e2) {

        } 

    }

}

我用ASTVisitor对象解析此代码并覆盖visit(CatchClause)方法:

 @Override
   public boolean visit(CatchClause node) {
      //some code here
      return true;
   }

对于带有对象e2的异常调用此方法,但对于匿名类中的异常,永远不会调用此方法。我不知道为什么。我应该改变什么?

匿名类的解析如下所示:

public boolean visit(AnonymousClassDeclaration node) {
   System.out.println("anonymous class");
   return true;
}

以下是重现该问题的完整工作示例:

import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.jdt.core.dom.ASTVisitor;
import org.eclipse.jdt.core.dom.AnonymousClassDeclaration;
import org.eclipse.jdt.core.dom.Assignment;
import org.eclipse.jdt.core.dom.CatchClause;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jdt.core.dom.ConditionalExpression;
import org.eclipse.jdt.core.dom.DoStatement;
import org.eclipse.jdt.core.dom.EnhancedForStatement;
import org.eclipse.jdt.core.dom.EnumDeclaration;
import org.eclipse.jdt.core.dom.FieldAccess;
import org.eclipse.jdt.core.dom.FieldDeclaration;
import org.eclipse.jdt.core.dom.ForStatement;
import org.eclipse.jdt.core.dom.ITypeBinding;
import org.eclipse.jdt.core.dom.IfStatement;
import org.eclipse.jdt.core.dom.ImportDeclaration;
import org.eclipse.jdt.core.dom.MethodDeclaration;
import org.eclipse.jdt.core.dom.MethodInvocation;
import org.eclipse.jdt.core.dom.PackageDeclaration;
import org.eclipse.jdt.core.dom.SwitchStatement;
import org.eclipse.jdt.core.dom.TypeDeclaration;
import org.eclipse.jdt.core.dom.VariableDeclarationFragment;
import org.eclipse.jdt.core.dom.WhileStatement;

public class Test {
    public static void main(String args[]){
        ASTParser parser = ASTParser.newParser(AST.JLS4);
        parser.setSource("package testpackage; import java.awt.Button; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class TestClass2 { public void test() { new Button().addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { try { } catch (Exception e1) { } } }); try { } catch (Exception e2) { } } }".toCharArray());

        parser.setKind(ASTParser.K_COMPILATION_UNIT);
        parser.setStatementsRecovery(true);
        parser.setResolveBindings(true);
        final CompilationUnit compilationUnit = (CompilationUnit) parser.createAST(null);
        compilationUnit.accept(new ASTVisitor() {

            @Override
            public boolean visit(TypeDeclaration node) {

                return true;
            }

            @Override
            public boolean visit(MethodDeclaration node) {

                return true;
            }

            @Override
            public boolean visit(ImportDeclaration node) {

                return false;
            }

            @Override
            public boolean visit(AnonymousClassDeclaration node) {

                return true;
            }

            @Override
            public boolean visit(Assignment node) {

                return false;
            }

            @Override
            public boolean visit(CatchClause node) {
                System.out.println(node);
                return true;
            }

            @Override
            public boolean visit(ConditionalExpression node) {

                return true;
            }

            @Override
            public boolean visit(DoStatement node) {

                return true;
            }

            @Override
            public boolean visit(EnhancedForStatement node) {

                return true;
            }

            @Override
            public boolean visit(EnumDeclaration node) {

                return false;
            }

            @Override
            public boolean visit(FieldDeclaration node) {

                return false;
            }

            @Override
            public boolean visit(ForStatement node) {

                return true;
            }

            @Override
            public boolean visit(IfStatement node) {

                return true;
            }

            @Override
            public boolean visit(MethodInvocation node) {

                return false;
            }

            @Override
            public boolean visit(PackageDeclaration node) {

                return false;
            }

            @Override
            public boolean visit(SwitchStatement node) {

                return true;
            }

            @Override
            public boolean visit(WhileStatement node) {

                return true;
            }

            @Override
            public boolean visit(FieldAccess node) {

                return false;
            }

        });

    }
}

2 个答案:

答案 0 :(得分:0)

通过覆盖ASTParser上的访问方法,您应该在捕获它们时显式访问任何节点

答案 1 :(得分:-1)

这是因为您没有访问方法调用addActionListener

更改visit(MethodInvocation node)以返回true

public boolean visit(MethodInvocation node) {

    return true;
}