使用 Eclipse JDT 查找特定节点内可见的所有标识符 [英] Using Eclipse JDT to find all identifiers visible within a specific node
问题描述
我正在开发一个 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.
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;
orimport 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屋!