java

2009-06-30 12 views
6

için Ek Açıklama İşlemcisindeki bir yöntem sınıfının sınıfını keşfedin Yapı sistemimiz için bazı ek açıklamaları içeren sınıflara ait yöntemlerle ilgili bazı katı çağrı kurallarını uygulamak için bazı araçlar yazıyorum. Ben Derleyici Ağacı API kullanıyorumjava

...

Bir MethodInvocation için sınıf/arayüzün türünü söyleyebilir nasıl ben 'ağaç' baştan bir zaman merak ediyorum ne

.

Birlikte TreePathScanner sınıflara ediyorum:

@Override 
public Object visitMethodInvocation(MethodInvocationTree node, Trees trees) { 

} 

Ben umuyorum üzerinde yöntemini çağırmak için çalışıyoruz sınıfının (veya arayüz) türünü söylemek üzere bir yolu vardır. Bunu yanlış yoldan mı yapıyorum? Herhangi bir fikir için teşekkürler ...

cevap

8

Burada birkaç sorun var. Ya da yöntem çağırma alıcısının Java türünü bilerek ile ilgilenebilir ya da yöntemin uygulandığı sınıfı öğrenmek için sadece . Java bilgisi, örneğin, genel türleri de sağladığından, daha fazla bilgidir. List<String> , Öğeler yalnızca sınıfı, örn. List<E>.


    MethodInvocationTree node = ...; 
    Element method = 
     TreeInfo.symbol((JCTree)node.getMethodSelect()); 
    TypeElement invokedClass = (TypeElement)method.getEnclosingElement(); 

Köşe durumlarda:

1.

yöntem üzerinde çağrıldığında sınıfın Eleman almak için Eleman

alınıyor, aşağıdaki yapabilirsiniz invokedClass alıcı tipinin bir süper sınıfı olabilir. Yani new ArrayList<String>.equals(null) üzerinde pasajı çalışan() AbstractList değil ArrayList içinde uygulanmaktadır eşittir beri AbstractList yerine ArrayList, dönecekti. Dizi çağırmalarını ele alırken, örn. new int[].clone(), sınıfının Array numarasını alırsınız.

türü almak için gerçek türü

Alma, alıcı tipi ne onu belirlemek için doğrudan bir yol yoktur. Alıcının açıkça (örneğin, OuterClass.this.toString()'dan farklı olarak) verilmediği iç sınıflar içinde yöntem çağırmalarının ele alınmasında bazı karmaşıklıklar vardır. Aşağıda örnek bir uygulamasıdır:


    MethodInvocationTree node = ...; 
    TypeMirror receiver; 
    if (methodSel.getKind() == Tree.Kind.MEMBER_SELECT) { 
    ExpressionTree receiver = ((MemberSelectTree)methodSel).getExpression(); 
    receiverType = ((JCTree)receiver).type; 
    } else if (methodSel.getKind() == Tree.Kind.IDENTIFIER) { 
    // need to resolve implicit this, which is described in 
    // JLS3 15.12.1 and 15.9.2 

    // A bit too much work that I don't want to work on now 
    // Look at source code of 
    // Attr.visitApply(JCMethodInvocation) 
    // resolveImplicitThis(DiagnosticPosition, Env, Type) 
    } else 
    throw new AssertionError("Unexpected type: " + methodSel.getKind()); 

Not:

receiver tip maalesef TypeMirror değil DeclaredType olması gerekiyor. new int[5].clone(), receiver numaralı telefonu arayarak, ve ArrayType numaralı ArrayType, önceki yönteminden daha bilgilendirici olur.önceki yöntemlerden

İkisi çalışmasına alınıyor

sınıflar için tip bilgileri çözmek için derleyici gerektirir. Her zamanki durumda, derleyici yalnızca yöntem beyanları türlerini değil, yalnızca gövdeleri çözer. Bu nedenle, daha önce açıklanan yöntemler, bunun yerine null döndürecektir. Sadece JDK 7. Geliş iş için derleyici deposuna ilave got

1. Kullanım AbstractTypeProcessor sınıfı:

Eğer birini aşağıdaki yolları yapabilir, derleyici tür bilgisi gidermek sahibi olmak JSR 308 ve derleyicileri. Çalışma esas olarak açıklamalı türlerde olsa da, bunun için yararlı olabilir. derleyici Eğer bu yaklaşım sadece mevcut işlemciler gibi çağrılan olsun işlemcileri yazmasına olanak tanır Java 5.

ile geriye uyumlu biçimde sağlanan sınıfını kullanmasını sağlar.

2. JavacTask kullanın ve JavacTask.analyze() numaralı telefonu arayın. 'un ziyaretçinizi sınıflarda nasıl çağırdığını görmek için this javac test ana yöntemini ana yöntemine bakın.

Bu yaklaşım, işlemcinizin bir derleyici eklentisi yerine gibi bir analiz aracı gibi görünmesini sağlar; çünkü bu işlem normal bir işlem olmak yerine, doğrudan numaralı telefonu çağırmanız gerekir.

+0

Yanıt için teşekkür ederiz. Ancak, satır: Öğe yöntemi = TreeInfo.symbol ((JCTree) node.getMethodSelect()); , benim için null değerini döndürüyor. \t TypeMirror m = trees.getTypeMirror (yol); ayrıca, \t TypeElement e = (TypeElement) ağaçları.getElement (yol); Çaylak bir hata yapıyor ve bir şeyi başlatmayı veya yanlış yöntemi çağırmayı/geçersiz kılmayı veya yanlış bir şeyi alt sınıfta tutmayı unutuyor muyum? Yardımınız için tekrar teşekkürler ... – runT1ME

+0

Yalnızca girdilerin neden dönmediğini ve – notnoop

+0

FYI adresinin nasıl çözüleceğini açıklamak için girdiyi güncelleştirdim, JSR 308 desteği artık kullanılmadığı için JDT 7'de AbstractTypeProcessor artık kullanılamıyor. –