对于我们在大学的主项目,我们使用 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
which ingetImportedNamespaceResolvers
添加 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
并且也找不到例如布尔值或其他任何东西。
问题当然是:我们做错了什么还是我们必须做的其他事情。当我们有一个小得多的项目时,它曾经可以工作,但在一些重大更改之后突然停止工作。