Xtext 自定义验证器警告 - 如何标记关键字?
Xtext custom validator warning - How to mark keyword?
我在 xtext 中有简单的问候语示例。所以DSL是这样定义的:
grammar org.xtext.example.mydsl.Tests with org.eclipse.xtext.common.Terminals
generate tests "http://www.xtext.org/example/mydsl/Tests"
Model:
greetings+= Greeting*;
Greeting:
'Hello' name=ID '!';
此外,我有以下验证器:
@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
if (!Character.isUpperCase(greeting.name.charAt(0))) {
warning('Name should start with a capital',
TestsPackage.Literals.GREETING__NAME,
-1,
INVALID_NAME)
}
}
如果我这样写验证器并且有一个像这样的表达式
"Hello world!"
在我的模型中,"world" 被标记,即它下面有这条黄线。如果我只想标记关键字(在本例中只标记 "Hello"),我该怎么办?
我尝试了很多东西,但我只能设法标记整行 "Hello world!" 或仅标记 "world".
谢谢!
查看其他报告 warning/error 的方法。有一个需要偏移量和长度。您可以使用节点模型为关键字获取它们
class MyDslValidator extends AbstractMyDslValidator {
public static val INVALID_NAME = 'invalidName'
@Inject extension MyDslGrammarAccess
@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
if (!Character.isUpperCase(greeting.name.charAt(0))) {
val node = NodeModelUtils.findActualNodeFor(greeting)
for (n : node.asTreeIterable) {
val ge = n.grammarElement
if (ge instanceof Keyword && ge == greetingAccess.helloKeyword_0) {
messageAcceptor.acceptWarning(
'Name should start with a capital',
greeting,
n.offset,
n.length,
INVALID_NAME
)
}
}
}
}
}
我发现了另一个我没有想到的非常简单的解决方案,包括稍微更改 DSL,即将关键字添加为属性。
Greeting:
keyword='Hello' name=ID '!';
然后验证器按照问题工作:
@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
if (!Character.isUpperCase(greeting.name.charAt(0))) {
warning('Name should start with a capital',
TestsPackage.Literals.GREETING__KEYWORD,
-1,
INVALID_NAME)
}
}
我在 xtext 中有简单的问候语示例。所以DSL是这样定义的:
grammar org.xtext.example.mydsl.Tests with org.eclipse.xtext.common.Terminals
generate tests "http://www.xtext.org/example/mydsl/Tests"
Model:
greetings+= Greeting*;
Greeting:
'Hello' name=ID '!';
此外,我有以下验证器:
@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
if (!Character.isUpperCase(greeting.name.charAt(0))) {
warning('Name should start with a capital',
TestsPackage.Literals.GREETING__NAME,
-1,
INVALID_NAME)
}
}
如果我这样写验证器并且有一个像这样的表达式 "Hello world!" 在我的模型中,"world" 被标记,即它下面有这条黄线。如果我只想标记关键字(在本例中只标记 "Hello"),我该怎么办? 我尝试了很多东西,但我只能设法标记整行 "Hello world!" 或仅标记 "world".
谢谢!
查看其他报告 warning/error 的方法。有一个需要偏移量和长度。您可以使用节点模型为关键字获取它们
class MyDslValidator extends AbstractMyDslValidator {
public static val INVALID_NAME = 'invalidName'
@Inject extension MyDslGrammarAccess
@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
if (!Character.isUpperCase(greeting.name.charAt(0))) {
val node = NodeModelUtils.findActualNodeFor(greeting)
for (n : node.asTreeIterable) {
val ge = n.grammarElement
if (ge instanceof Keyword && ge == greetingAccess.helloKeyword_0) {
messageAcceptor.acceptWarning(
'Name should start with a capital',
greeting,
n.offset,
n.length,
INVALID_NAME
)
}
}
}
}
}
我发现了另一个我没有想到的非常简单的解决方案,包括稍微更改 DSL,即将关键字添加为属性。
Greeting:
keyword='Hello' name=ID '!';
然后验证器按照问题工作:
@Check
def checkGreetingStartsWithCapital(Greeting greeting) {
if (!Character.isUpperCase(greeting.name.charAt(0))) {
warning('Name should start with a capital',
TestsPackage.Literals.GREETING__KEYWORD,
-1,
INVALID_NAME)
}
}