从语法 B 的验证器引用语法 A 的 Xtext 问题



在 Xtext 中,如何在语法 B 的验证器(在 ui 插件中(中跟踪从语法 B 到语法 A 的引用?请考虑以下示例。

语法 A 是org.xtext.people.People

grammar org.xtext.people.People with org.eclipse.xtext.common.Terminals
generate people "http://www.xtext.org/people/People"
People:
people+=Person*;
Person:
'person' name=ID ';';

和一个实例

person Alice {citizenship "MN"; id "12345"; }
person Bob {citizenship "CH"; id "54321";}
person Malice {citizenship "XXX"; id "66666"; }

在机场,记录人员的入境。

enter Alice;
enter Bob;
enter Malice; 

条目使用第二个语法 Borg.xtext.entries.Entries

建模
grammar org.xtext.entries.Entries with org.eclipse.xtext.common.Terminals
generate entries "http://www.xtext.org/entries/Entries"
import "http://www.xtext.org/people/People"
Entries:
entries+=Entry*;
Entry:
'enter' person=[Person] ';';

在确保 Eclipse 项目org.xtext.entries在其类路径上具有项目org.xtext.people,并确保org.xtext.entries插件将org.xtext.people作为依赖项之后,一切都按预期工作。

来自XXX国的人有旅行禁令,尽管某些应得的人被排除在外。只有中央情报局知道谁被排除在禁令之外。除非被排除在外,否则不得允许来自XXX的人参加。

更新后的语法是

grammar org.xtext.entries.Entries with org.eclipse.xtext.common.Terminals
generate entries "http://www.xtext.org/entries/Entries"

import "http://www.xtext.org/people/People"
Entries:
entries+=Entry*;
Entry:
travelBanOverride=TravelBanOverride?
'enter' person=[Person] ';';
TravelBanOverride: '@TravelBanOverride' '(' code=STRING ')';

带验证器

package org.xtext.entries.validation
import org.eclipse.xtext.validation.Check
import org.xtext.entries.entries.EntriesPackage
import org.xtext.entries.entries.Entry
import org.xtext.entries.CIA
class EntriesValidator extends AbstractEntriesValidator {
public static val BAN = 'BAN'
public static val ILLEGAL_OVERRIDE = 'ILLEGAL_OVERRIDE'
@Check
def checkBan(Entry entry) {
if (entry.person.citizenship == "XXX") {
if (entry.travelBanOverride === null) {
error('Violation of Travel Ban', EntriesPackage.Literals.ENTRY__PERSON, BAN)
} 
else {
val overridecode = entry.travelBanOverride.code;
val valid = CIA.valid(entry.person.name, entry.person.id, overridecode)
if (!valid) {
error('Illegal override code', EntriesPackage.Literals.ENTRY__TRAVEL_BAN_OVERRIDE, ILLEGAL_OVERRIDE)
}
}
}
}
}

其中,外部 CIA Web 应用程序的驱动程序建模

,例如由
package org.xtext.entries;
public class CIA {

public static boolean valid(String name, String id, String overrideCode) {
System.out.println("UNValid["+name+","+overrideCode+"]");
return name.equals("Malice") && id.equals("66666") && overrideCode.equals("123");
}
}

验证按预期工作。

我现在希望为BAN提供一个快速修复,检查中央情报局的覆盖代码。

package org.xtext.entries.ui.quickfix
import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider
import org.eclipse.xtext.ui.editor.quickfix.Fix
import org.xtext.entries.validation.EntriesValidator
import org.eclipse.xtext.validation.Issue
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor
import org.xtext.entries.entries.Entry
import org.xtext.entries.Helper
class EntriesQuickfixProvider extends DefaultQuickfixProvider {
@Fix(EntriesValidator.BAN)
def tryOverride(Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue, 'Try override', 'Override if CIA says so.', 'override.png') 
[element ,context |
val entry = element as Entry
// val person = entry.person // no such attribute
//val person = Helper.get(entry); // The method get(Entry) from the type Helper refers to the missing type Object
]
}
}

第一个注释行不编译:没有属性person。第二行注释是试图通过获取帮助程序类来解决问题org.xtext.entries以获取人员,但这也不会编译,给出"来自类型帮助程序的方法get(Entry(引用缺少的类型对象">错误消息。

为了完整起见,这里是那个帮助程序。

package org.xtext.entries
import org.xtext.people.people.Person
import org.xtext.entries.entries.Entry
class Helper {
static def Person get(Entry entry) {
return entry.person;
}
}

此外,entry.travelBanOverride编译得很好,但entry.person不能。 在 Eclipse 中单击条目会将您带到预期的代码,该代码同时具有travelBanOverrideperson

同一项目和包中的 Java 类不会出现此问题。

package org.xtext.entries.ui.quickfix;
import org.xtext.entries.entries.Entry;
import org.xtext.people.people.Person;
public class Test {
public static void main(String[] args) {
Entry entry = null;
Person p = entry.getPerson();
}
}

在 Java 中重写快速修复可以解决此问题。

package org.xtext.entries.ui.quickfix;
import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider;
import org.eclipse.xtext.ui.editor.quickfix.Fix;
import org.xtext.entries.validation.EntriesValidator;
import org.eclipse.xtext.validation.Issue;
import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor;
import org.xtext.entries.entries.Entry;
import org.xtext.entries.Helper;
import org.eclipse.xtext.ui.editor.model.edit.IModificationContext;
import org.eclipse.xtext.ui.editor.model.edit.ISemanticModification;
import org.eclipse.emf.ecore.EObject;
import org.xtext.entries.entries.Entry;
import org.xtext.people.people.Person;
public class EntriesQuickfixProvider extends DefaultQuickfixProvider {

@Fix(EntriesValidator.BAN)
public void tryOverride(final Issue issue, IssueResolutionAcceptor acceptor) {
acceptor.accept(issue,
"Try to override", 
"Override",
"override.gif", 
new ISemanticModification() {
public void apply(EObject element, IModificationContext context) {
Entry entry = (Entry) element;
System.out.println(entry.getPerson());
}
}
);
}
}
  • 如何在语法 B 的验证器中遵循从语法 B(条目(到语法 A(人员(的引用?

我的错误如下。

在确保 Eclipse 项目 org.xtext.entries 具有 在其类路径上投影 org.xtext.people,并确保 org.xtext.entries 插件将 org.xtext.people 作为依赖项,所有 按预期工作。

org.xtext.entries.uiui-plugin还必须在其 Java(Eclipse 项目(构建路径上具有org.xtext.people。导出并制作插件依赖项是不够的。

请注意,应在制定快速修复之前尽早进行此设置,因为 Xtend 编辑器存在刷新问题。

最新更新