私は変数/識別子の名前、たとえば、、x
およびとJCCompilationUnit
を持っています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
取得を可能にするいくつかのユーティリティメソッドがあり、したがって、を取得できます(これは変数宣言からのものであるため)。現在、-を返すメソッドがありますが、実際には、これは、、、および(単純な参照型および型変数の場合)のいずれかです。したがって、タイプのみを印刷する場合は、これで十分な場合があります。それ以外の場合は、クラスを使用して、このタイプのTypeMirrorを取得できます。Tree
TreePath
Element
VariableTree
VariableTree
getType()
Tree
PrimitiveTypeTree
ParametrizedTypeTree
ArrayTypeTree
IdentifierTree
Trees
(フォーマットされたソースコードも出力する新しいDocletを書き込もうとしたときに、同じようなことをしたことがあります。これらすべてのAPI間でひどい反転が発生します。)