使用Eclipse JDT查找在特定节点内可见的所有标识符 [英] Using Eclipse JDT to find all identifiers visible within a specific node

查看:65
本文介绍了使用Eclipse JDT查找在特定节点内可见的所有标识符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发Eclipse JDT的插件,该插件可解析Java文件并对其进行自动更正.我正在使用Eclipse的API来分析AST.

I'm working on a plug-in to Eclipse JDT that parses Java files and offers automatic corrections to them. I'm doing so using Eclipse's API for analyzing the AST.

我正在尝试写一种方法来计算环境方法-在方法范围内可见的所有标识符的列表.另一种查看方式是可以从Eclipse中的特定点自动完成的标识符列表.

I'm trying to write a method that calculates the environment of a method - a list of all the identifiers that are visible within the scope of the method. Another way to look at this is the list of identifiers that can be auto-completed from a specific point in Eclipse.

例如:

import ...

public class MyClass {
    private static final int a = 3;
    private boolean b;

    float someMethod(String s) {
        int c = 3;
        (X);    
    }
}

(X)中的环境由标识符 a b c s .

The environment in (X) is composed of the identifiers a, b, c and s.

如何在Eclipse中计算方法的环境?

How can I calculate the environment of a method in Eclipse?

推荐答案

以下是一些有效的代码,可以解决给定的简单示例,但是需要扩展以获取更多信息复杂代码:

Here is some working code that solves the given simple example, but needs to be extended for more complex code:

  • 范围,例如G. int a = 1;{int b = 2;}(X)(环​​境:仅 a )
  • 继承
  • 带有或不带有通配符的静态导入,例如G.导入静态java.lang.Integer.MAX_VALUE; import静态java.lang.Integer.*;
  • ...

基本原理是传播AST并通过 node.resolveBinding()访问交叉连接.

The basic principle is to travel the AST and access cross connections via node.resolveBinding().

public class Environment {

    public static void main(String[] args) {
        String code = "public class MyClass {\n" +
                "    private static final int a = 3;\n" +
                "    private boolean b;\n" +
                "\n" +
                "    float someMethod(String s) {\n" +
                "        int c = 3;\n" +
                "        // (X);\n" +
                "    }\n" +
                "}";
        for (IBinding binding : of(code, code.indexOf("(X)"))) {
            System.out.println(binding.getName());
        }
    }

    public static List<IBinding> of(String code, int offset) {
        final List<IBinding> environment = new ArrayList<>();
        createAst(code).accept(new ASTVisitor(true) {

            public boolean visit(VariableDeclarationFragment node) {
                if (offset < node.getStartPosition()) return false;
                environment.add(node.resolveBinding());
                return true;
            }

            public boolean visit(SingleVariableDeclaration node) {
                if (offset < node.getStartPosition()) return false;
                environment.add(node.resolveBinding());
                return true;
            }

        });
        return environment;
    }

    private static CompilationUnit createAst(String code) {

        // parser
        ASTParser parser = ASTParser.newParser(AST.JLS10);
        parser.setKind(ASTParser.K_COMPILATION_UNIT);
        parser.setResolveBindings(true);
        parser.setBindingsRecovery(true);
        parser.setStatementsRecovery(true);

        // options
        final Hashtable<String, String> options = JavaCore.getOptions();
        options.put("org.eclipse.jdt.core.compiler.source", "1.8");
        parser.setCompilerOptions(options);

        // sources and classpath
        String[] sources   = new String[] { /* source folders */ };
        String[] classpath = new String[] { /* JARs */};
        String[] encodings = new String[sources.length];
        Arrays.fill(encodings, StandardCharsets.UTF_8.name());
        parser.setEnvironment(classpath, sources, encodings, true);
        parser.setUnitName("code");
        parser.setSource(code.toCharArray());

        // abstract syntax tree
        return (CompilationUnit) parser.createAST(null);
    }

}

或者,可以通过 node.getFields()处的方法的参数在 visit(TypeDeclaration节点)处收集字段(包括常量).通过AST中的 node.parameters()来访问(MethodDeclaration节点).

Alternatively, the fields (including constants) can be collected at visit(TypeDeclaration node) via node.getFields() or the parameters of a method at visit(MethodDeclaration node) via node.parameters() earlier in the AST.

这篇关于使用Eclipse JDT查找在特定节点内可见的所有标识符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆