Java TreeコンパイラAPIを使用して識別子のタイプ宣言を見つけるにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/4881389

質問

私は変数/識別子の名前を持っています、たとえば、 x, 、 そしてその JCCompilationUnitScope. 。タイプを見つける方法はありますか x?

役に立ちましたか?

解決

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

編集: ええ、本当にテストされていません(noはありません getType() 方法)。

だから、aから取得する方法 Element そのタイプから(または可変エレメント)?

Trees クラスにはいくつかのユーティリティ方法があり、 Tree また TreePath から Element, 、したがって、aを取得できます VariableTree (これは変数宣言から来たので)。 VariableTree 今があります getType() メソッド、aを返します Tree - しかし、実際にはこれはの1つです PrimitiveTypeTree, ParametrizedTypeTree, ArrayTypeTreeIdentifierTree (単純な参照タイプとタイプ変数の場合)。したがって、タイプを印刷したい場合は、これで十分かもしれません。そうでなければ、再び Trees クラスこのタイプのタイプミラーを入手できます。

(フォーマットされたソースコードを出力する新しいドキュレットを書き込もうとしたときに、私は一度似たことをしました。これらすべてのAPIの間でひどい反転。)

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top