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

查看:18
本文介绍了使用 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)中的环境由标识符abcs.

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.import static java.lang.Integer.MAX_VALUE;import static java.lang.Integer.*;
  • ...
  • Scopes, e. g. int a = 1; { int b = 2; } (X) (environment: a only)
  • Inheritance
  • Static imports with or without wildcards, e. g. import static java.lang.Integer.MAX_VALUE; or import static java.lang.Integer.*;
  • ...

基本原理是通过node.resolveBinding()遍历AST和访问交叉连接.

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 {
" +
                "    private static final int a = 3;
" +
                "    private boolean b;
" +
                "
" +
                "    float someMethod(String s) {
" +
                "        int c = 3;
" +
                "        // (X);
" +
                "    }
" +
                "}";
        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 node) 处的方法参数收集字段(包括常量)在 AST 中通过 node.parameters() 访问(MethodDeclaration node).

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天全站免登陆