2

对于我们在大学的主项目,我们使用 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
}

我们已经尝试过使用ImportedNamespaceAwareLocalScopeProviderwhich 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并且也找不到例如布尔值或其他任何东西。

问题当然是:我们做错了什么还是我们必须做的其他事情。当我们有一个小得多的项目时,它曾经可以工作,但在一些重大更改之后突然停止工作。

4

0 回答 0