Xtext Validation 拆分为多个插件

Xtext Validation split over multiple plugins

我希望根据加载的插件激活不同的验证。

mylang.database 插件应该提供类似

的警告
    mylangElement {
       id = "helloWorld"  //Warning id should start with an upper case
    }

mylang.server 插件应该像

那样发出警告
    mylangElement {
       id = "helloWorld"  //Warning id must not exceed 8 letters
    }

(如果两个插件都存在,则可能两者都有)

推荐的方法是什么?

您是否考虑过简单地挂接到 xtext 已经使用的验证机制。我假设你的意思是 "loaded" 包含验证器的插件已激活(因此插件已激活)

然后你可以做这样的事情(在激活器启动时)

MyValidator val = new MyValidator();
Injector injector = IResourceServiceProvider.Registry.INSTANCE.getResourceServiceProvider(URI.createURI("dummy.mydsl")).get(Injector.class);
injector.injectMembers(val);

使用我的验证器

public class MyValidator extends AbstractDeclarativeValidator {

    public static final String INVALID_NAME = "invalidName";

    @Override
    protected List<EPackage> getEPackages() {
        return Collections.singletonList(MyDslPackage.eINSTANCE);
    }

    @Check
    public void checkGreeting(Greeting g) {
        if (!Character.isUpperCase(g.getName().charAt(0))) {
            warning("Name should start with a capital", MyDslPackage.Literals.GREETING__NAME, INVALID_NAME);
        }
    }

}

或者您可以创建一个 class 如下所示

public class MyValidator extends AbstractDeclarativeValidator {

    public static final String INVALID_NAME = "invalidName";

    @Override
    protected List<EPackage> getEPackages() {
        return Collections.singletonList(MyDslPackage.eINSTANCE);
    }

    @Check(CheckType.FAST)
    public void checkFast(EObject g) {
        // TODO
    }
    @Check(CheckType.NORMAL)
    public void checkNormal(EObject g) {
        // TODO
    }
    @Check(CheckType.EXPENSIVE)
    public void checkExpensive(EObject g) {
        // TODO
    }

}

将其绑定到 MyDslRuntime 或更喜欢的 uimodule 中

class MyDslUiModule extends AbstractMyDslUiModule {

    @SingletonBinding(eager=true) def Class<? extends MyValidator> bindMyValidator() {
        return MyValidator
    }
}

并用您自己的机制(例如自己的扩展点等)填充待办事项