2012-12-17 168 views
2

在的Xtext,我想寫一個實用方法返回在集合類型由JvmTypeReference代表由解析器創建的集合型(通用型),我需要知道的類型參數: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>我期望方法返回java.lang.String, 示例2:用於輸入java.util.Set<a.b.m.Book>返回a.b.m.Book

我需要我的生成器的集合類型參數類型。

然而,有前途的探測typeReferences.getArgument(..)返回JvmParameterizedTypeReference: E其中getType()給出JvmTypeParameter <E> java.util.List。嗯。我進入了盲人的小巷。

它甚至可能或類型擦除也適用於JvmTypeReference?我希望不是。

謝謝你的任何提示。

回答

0

已解決。 getCollectionType()是正確的。什麼是不正確的是輸入,我如何創建JvmTypeReference。它們不是直接來源於解析的模型。只有頂層元素在我的DSL中明確指定了類型。所有子元素類型都是使用Xtext「introspection」以層疊方式從頂部到底部推斷的。推斷類型存儲在模型本身中;各種其他的東西都依賴於它們,比如驗證。要在Model AST中存儲推斷的JvmTypeReference,必須複製它。

我沒有正確創建副本。錯誤的庫調用。

錯誤:

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

正確:

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

嘛,TypeReferences#createTypeRef()也不是完全錯誤的。它創建了所需類型的副本,但呈現類似於Java中的「類型擦除」。

我把這個問題也放在Xtext forum上。

查看我的DeepCloneDSL項目的完整源代碼。

P.S.
爲什麼我們必須複製JvmTypeReference? Xtext常見類型的其他實例? JvmTypeReference是一個複雜類型,它是AST自己的一個片段,它是模型的一個片段。通過設置類型JvmType或類似的屬性,可以將模型片段插入到另一個模型;它不能同時插入兩次或兩個不同的模型。 Xtext本身防止了一些操作,其中一些更棘手,必須找到the hard way