使用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.
导入静态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屋!