2

Xtext で、パーサーによって作成された JvmTypeReference によってコレクション型が表されるコレクション型 (ジェネリック型) を返すユーティリティ メソッドを作成しようとしています。型パラメーターを知る必要があります。

@Inject TypeReferences typeReferences;
public JvmType getCollectionType(JvmTypeReference clazz) {
    if (typeReferences.isInstanceOf(clazz, Collection.class)) {
        collectionType = typeReferences.getArgument(clazz, 0);
        return collectionType;
    }
}

例 1: 入力java.util.List<String>の場合、メソッドは を返すと予想します。例 2:java.lang.String入力の場合java.util.Set<a.b.m.Book>は を返しa.b.m.Bookます。

ジェネレーターのコレクション型パラメーター型が必要です。

しかし、有望に聞こえますが、どこにtypeReferences.getArgument(..)返されますか。うーん。袋小路に入りました。JvmParameterizedTypeReference: EgetType()JvmTypeParameter <E> java.util.List

それは可能ですか、それとも型消去は にも適用されJvmTypeReferenceますか? ないことを願っています。

ヒントをありがとう。

4

1 に答える 1

0

解決しました。はgetCollectionType()正しいです。正しくなかったのは入力であり、JvmTypeReference. それらは、解析されたモデルから直接発生したものではありません。私の DSL では、最上位の要素だけが型を明示的に指定しています。すべてのサブエレメント タイプは、Xtext の「イントロスペクション」を使用して、上から下にカスケード方式で推論されます。推論された型はモデル自体に格納されます。検証など、他のあらゆる種類のものはそれらに依存しています。推論された JvmTypeReference をモデル AST 内に格納するには、そのコピーを作成する必要があります。

コピーを正しく作成しませんでした。ライブラリ呼び出しが間違っています。

違う:

public JvmTypeReference createDefensiveCopyOfJvmTypeReference(JvmTypeReference typeReference) {
    return typeReferences.createTypeRef(typeReference.getType());
}

正しい:

public JvmTypeReference createDefensiveCopyOfJvmTypeReference(JvmTypeReference   typeReference) {
    return EcoreUtil.copy(typeReference);
}

まあ、それTypeReferences#createTypeRef()は完全に間違っているわけではありません。目的の型のコピーを作成しますが、Java と同様の「型消去」を示します。

この質問はXtext フォーラムにも投稿しました。

完全なソース コードについては、私のDeepCloneDSLプロジェクトを確認してください。

PS
のコピーを作成する必要があるのはなぜJvmTypeReferenceですか? Xtext 共通タイプの他のインスタンスはありますか? JvmTypeReferenceは複合型でEObjectあり、AST 自体のフラグメントであり、モデルのフラグメントです。type などの属性を設定することによりJvmType、モデル フラグメントを別のモデルに挿入します。2 回挿入したり、2 つの異なるモデルに同時に挿入したりすることはできません。そのようなアクションの中には、Xtext 自体によって妨げられるものもあれば、よりトリッキーなものもあり、難しい方法を見つける必要があります。

于 2012-12-18T14:13:42.510 に答える