Xtext:如何从JvmTypeReference获取集合类型参数(泛型)?

时间:2012-12-17 10:09:48

标签: java xtext

在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?我希望不会。

感谢您的任何提示。

1 个答案:

答案 0 :(得分:0)

解决。 getCollectionType()是正确的。不正确的是输入,我创建JvmTypeReference的方式。它们并非直接来自解析的模型。只有顶级元素在我的DSL中明确指定了类型。所有子元素类型都是使用Xtext“introspection”以级联方式从上到下推断出来的。推断类型存储在模型本身中;各种其他东西都依赖于它们,比如验证。要在模型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是一个复杂类型EObject,它本身就是AST的一个片段,是模型的一个片段。通过设置类型JvmType或类似的属性,可以将模型片段插入到另一个模型中;它不能插入两次或同时在两个不同的型号中。 Xtext本身阻止了一些这样的行为,有些行为更棘手,必须找到the hard way