对于我们在大学的主项目,我们使用Xtext创建了多个DSL。其中一个DSL是模型实体DSL,它允许用户创建具有属性和方法的类。
我们重用Xbase,因为当然,我们希望这些方法能够使用真正的编程语言,而不需要重新发明轮子:
grammar … with org.eclipse.xtext.xbase.Xbase
generate …
EntityModel:
'package' importedNamespace=QualifiedName
…
implementation=Entity;
Entity:
'entity' name=ValidID '{'
features+=Feature*
'}';
Feature:
LocalVariable | …;
LocalVariable:
'var' (isStatic?='static')? name=ValidID ':' type=JvmTypeReference;
由于某种原因,即使LocalVariable的类型设置为JvmTypeReference,当使用String时(在实际实现中),它总是会显示错误
Xtext:无法解析对JvmType'String'的引用
package com.example
Entity foo {
var bar: String
}
我们已经尝试使用ImportedNamespaceAwareLocalScopeProvider
getImportedNamespaceResolvers
添加java.lang。*,就像那样:
List<ImportNormalizer> implicitImports = super.getImportedNamespaceResolvers(context, ignoreCase);
List<ImportNormalizer> javaLangImports = singletonList(new ImportNormalizer(QualifiedName.create("java", "lang"), true, ignoreCase));
implicitImports.addAll(javaLangImports);
return implicitImports;
即使认为该方法被多次调用,导入仍然无效。检查EObject context
参数时,它有时会返回java.lang.String(我猜是JvmTypeReference
,但它仍然显示错误。
在RuntimeModule
中,新范围提供程序的配置如下:
public void configureIScopeProviderDelegate(com.google.inject.Binder binder) {
binder.bind(org.eclipse.xtext.scoping.IScopeProvider.class).annotatedWith(com.google.inject.name.Names.named(org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.NAMED_DELEGATE)).to(MasterDSLImportedNamespaceAwareLocalScopeProvider.class);
}
在我们配置的Workflow
fragment = scoping.ImportNamespacesScopingFragment {}
fragment = exporting.QualifiedNamesFragment {}
fragment = builder.BuilderIntegrationFragment {}
项目的其余部分已经非常复杂(一个项目中的4个Xtext DSL和多个生成器)。但除了完全不同的DSL之外,它们使用几乎相同的工作流程和RuntimeModule
配置。另一个DSL也使用JvmTypeReference
,但也没有找到布尔或其他任何东西。
当然,问题是:我们做错了什么还是我们还有其他事要做。它曾经在我们有一个小得多的项目时工作,但经过一些重大变化突然停止了工作。