这就是 xtext 枚举的工作方式。枚举文字成为关键字。
你基本上有两个选择
(1)摆脱关键字阴影ID规则
Table:
'table' name=MyID type=Type
;
MyID: ID | "COLUMN" | "ROW";
可能需要为 MyID 调整proposalprovider
(2) 以不同方式处理枚举。这仅适用于手动维护的元模型
MyEnum returns importedPackage::MyEnum : ID;
- 采用值转换器和内容有助于在解析时获得正确的错误并在编辑时获得正确的建议
例子
Model:
greetings+=Greeting*;
Greeting:
'Hello' name=ID value=MyEnumDataTypeRule;
//TO be save MyEnum wold be better declared in a separate metamodel
// for sake of easyness i work here with literals that seem to be unlikely to conflict
// to tell xtext there are literals A B and C
enum MyEnum:
A="___________a"|
B="___________b"|
C="___________c"
;
MyEnumDataTypeRule returns MyEnum:
ID
;
值转换器
class MyDslValueConverters extends DefaultTerminalConverters {
@Inject
MyEnumValueConverter myEnumValueConverter
@ValueConverter(rule = "MyEnumDataTypeRule")
def IValueConverter<MyEnum> MyEnumDataTypeRule() {
return myEnumValueConverter
}
}
class MyEnumValueConverter implements IValueConverter<MyEnum> {
override toString(MyEnum value) throws ValueConverterException {
return value.getName();
}
override toValue(String string, INode node) throws ValueConverterException {
try {
return MyEnum.valueOf(string)
} catch (IllegalArgumentException e) {
throw new ValueConverterException("MyEnum does not allow literal " + string, node, e)
}
}
def static void main(String[] args) {
MyEnum.valueOf("xxxx")
}
}
绑定
class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
override bindIValueConverterService() {
MyDslValueConverters
}
}
内容辅助
class MyDslProposalProvider extends AbstractMyDslProposalProvider {
override complete_MyEnumDataTypeRule(EObject model, RuleCall ruleCall, ContentAssistContext context, ICompletionProposalAcceptor acceptor) {
MyEnum.values.forEach[
acceptor.accept(createCompletionProposal(getName(),context))
]
}
}