回答

3
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; 
} 

我最後寫一個完整的class with resolving methods。繼承它,或傳遞TreeMaker(和其他參數),它可以變成靜態的。如果有人覺得它值得,那麼補丁是值得歡迎的。

1

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類有一些實用方法允許從Element一個TreeTreePath的檢索,因此,我們可以得到一個VariableTree(因爲這是來自一個變量聲明)。 VariableTree現在有一個getType()方法,它返回Tree - 但實際上這是PrimitiveTypeTree,ParametrizedTypeTree,ArrayTypeTreeIdentifierTree(對於簡單引用類型以及類型變量)之一。所以,如果你只想打印類型,這可能就足夠了。否則,再次使用Trees類,我們現在可以獲得此類型的TypeMirror。

(我做了類似的事情,一旦當我試圖寫一個新的Doclet這也將輸出格式化的源代碼。所有這些API之間可怕的翻轉。)

+0

稍微相關的錯誤我提出了嘗試:http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7017477(考慮投票) – simpatico 2011-02-11 09:54:46