我有一个变量/标识符的名称,比如,x
和JCCompilationUnit
and Scope
。有没有办法找到类型x
?
2 回答
public Symbol getSymbol(CompilationUnitTree cut, JCStatement stmt, List<JCExpression> typeParams, Name varName, List<JCExpression> args) {
java.util.List<Type> typeSyms = getArgTypes(typeParams, cut, stmt);
java.util.List<Type> argsSyms = getArgTypes(args, cut, stmt);
final Scope scope = getScope(cut, stmt);
Symbol t = contains(scope, typeSyms, varName, argsSyms); //first lookup scope for all public identifiers
TypeElement cl = scope.getEnclosingClass();
while (t == null && cl != null) { //lookup hierarchy for inacessible identifiers too
t = contains(elementUtils.getAllMembers(cl), typeSyms, varName, argsSyms);
final TypeMirror superclass = cl.getSuperclass();
if (superclass != null) {
cl = (TypeElement) ((Type) superclass).asElement();
}
}
return t;
}
public Symbol getSymbol(Name varName, Symbol accessor, CompilationUnitTree cut, JCStatement stmt) {
if (varName.contentEquals("class")) {
Symbol javaLangClassSym = getSymbol(cut, stmt, null, elementUtils.getName("java.lang.Class"), null);
JCIdent id = tm.Ident(javaLangClassSym);
JCExpression mName = tm.Select(id, elementUtils.getName("forName"));
JCLiteral idLiteral = tm.Literal(accessor.toString());
JCMethodInvocation mi = tm.Apply(List.<JCExpression>nil(), mName, List.<JCExpression>of(idLiteral));
Symbol s = getSymbol(mi, cut, stmt);
return s;
}
accessor = getTypeSymbol(accessor);
java.util.List<Symbol> enclosedElements = getEnclosedElements(accessor, cut, stmt);
Symbol s = contains(enclosedElements, null, varName, null);
return s;
}
我最终用解决方法编写了一个完整的类。继承它,或者传入 TreeMaker(和其他参数),它可以是静态的。如果有人觉得它有价值,欢迎提供补丁。
该Scope
对象有一个方法getLocalElements()
,可以迭代。然后可以通过其名称询问每个元素,当这是正确的名称时(它也是一个变量),您可以获得它的类型。
这是未经测试的概念:
private final static Set<ElementKind> variableKinds =
Collections.unmodifiableSet(EnumSet.of(ElementKind.FIELD, ElementKind.ENUM_CONSTANT,
ElementKind.PARAMETER, ElementKind.LOCAL_VARIABLE));
public Type getTypeOfVariable(Scope scope, String varName)
{
for(Element e : scope.getLocalElements()) {
if(variableKinds.contains(e.getKind()) && e.getName().equals(varName)) {
return e.getType();
}
}
throw new NoSuchElementException("No variable " + varName + " in " + scope);
}
编辑:是的,真的未经测试(没有getType()
方法)。
那么,如何从一个Element
(或 VariableElement)中获取它的类型呢?
该类Trees
有一些实用方法允许从 中检索 a或Tree
,因此我们可以得到 a (因为它来自变量声明)。现在有一个方法,它返回一个- 但实际上这是一个, ,和(对于简单的引用类型以及类型变量)。因此,如果您只想打印类型,这可能就足够了。否则,再次使用该类,我们现在可以获得该类型的 TypeMirror。TreePath
Element
VariableTree
VariableTree
getType()
Tree
PrimitiveTypeTree
ParametrizedTypeTree
ArrayTypeTree
IdentifierTree
Trees
(当我尝试编写一个新的 Doclet 时,我做过类似的事情,它也会输出格式化的源代码。在所有这些 API 之间进行可怕的翻转。)