in-editor error message on the wrong cross-reference [message #1750955] |
Mon, 02 January 2017 19:36 |
|
Below the grammar I use:
grammar com.septentrio.infrastructure.flax.Flax with org.eclipse.xtext.common.Terminals
generate language "http://www.septentrio.com/infrastructure/flax/Flax"
Flax:
('package' name=QualifiedName)?
(imports+=Import)*
(entities+=Entity)*;
Import:
'import' importedNamespace=QualifiedNameWithWildcard;
QualifiedName:
ID ('.' ID)*;
QualifiedNameWithWildcard:
QualifiedName '.*'?;
Entity:
Tag|Class;
Tag:
'tag' name=ID
( '{' properties+=TagProperty* '}' )?;
TagProperty:
name=ID;
Class:
tagrefs+=TagReference*
'class' name=ID
( 'extends' (parents+=[Class|QualifiedName]','?)+ )?
( '{' sections+=Section* '}' )?;
TagReference:
'@' tag=[Tag]
( '(' ( arguments+=[TagProperty|QualifiedName] ','? )* ')' )?;
Section:
PropertySection|MethodSection;
PropertySection:
'properties' '{' properties+=Property* '}';
MethodSection:
'methods' '{' methods+=Method* '}';
Member:
Property|Method;
Property:
type=ElementType name=ID;
Method:
type=ElementType? name=ID
( '(' (parameters+=Parameter','?)* ')' )?
body=Block;
Block:
'{' (expressions+=Expression)* '}';
ElementType:
BasicType|ClassType;
BasicType:
type=('void'|'any'|'enum'|'logical'|'string'|'integer'|'float');
ClassType:
type=[Class|QualifiedName];
Parameter:
type=ElementType name=ID;
Symbol:
Entity|Parameter|Member;
Expression:
Primary ( {Selection.operand=current} levels+=SelectionLevel )*;
Primary returns Expression:
'(' Expression ')' |
{Boolean} value=('true'|'false') |
{Integer} value=INT |
{SymbolReference} symbol=[Symbol] => Parameters? |
{Metadata} '?' name=ID;
SelectionLevel returns Expression:
{MemberSelection} '.' name=[Member] => Parameters?;
fragment Parameters:
parameterized ?= '(' (parameters+=Expression','?)* ')';
and I have this validation check:
@Check
def duplicateArgument(TagReference t) {
val visited = <TagProperty>newArrayList
for (argument: t.arguments)
if (visited.contains(argument))
error(
'''Duplicate argument "«argument.name»" for tag "«t.tag.name»" for class "«t.getContainerOfType(Class).name»"''',
LanguagePackage.Literals.TAG_REFERENCE__ARGUMENTS,
DUPLICATE_ELEMENT
)
else
visited.add(argument)
}
If I give this to the resulting editor plugin:
tag Animal {
Running
Sleeping
}
@Animal(Running, Sleeping, Sleeping)
class Horse
then the error message is correctly indicating that the "Sleeping" tag argument is duplicate BUT it underlines the "Running" tag argument instead... which is not what I would expect.
As far as I understand, the validation check takes an EObject as input and must report an error on an EStructuralFeature. Since the structure feature of the form "argument+=...", how can I specify which element of the list is in error?
[Updated on: Tue, 03 January 2017 23:13] Report message to a moderator
|
|
|
Re: in-editor error message on the wrong cross-reference [message #1750956 is a reply to message #1750955] |
Mon, 02 January 2017 19:46 |
|
Hi,
there are tons of methods with different signatures to report the error
e.g. one that takes an index as well e.g.
@Check
def duplicateArgument(TagReference t) {
val visited = <TagProperty>newArrayList
var index = 0;
for (argument: t.arguments) {
if (visited.contains(argument))
error(
'''Duplicate argument "«argument.name»" for tag "«t.tag.name»" for class "«EcoreUtil2.getContainerOfType(t,Class).name»"''',
MyDslPackage.Literals.TAG_REFERENCE__ARGUMENTS,
index,
"ERROR_CODE"
)
else
visited.add(argument)
index+=1
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com
|
|
|
Re: in-editor error message on the wrong cross-reference [message #1750960 is a reply to message #1750956] |
Mon, 02 January 2017 23:07 |
|
I missed those for some reason... it is exactly what I need.
I also discovered that the ValidationTestHelper.assertError() method had a form with offset and length to write the corresponding test.
For the record, I wrote the test like this:
@Test
def void testDuplicateClassTagReferenceArgument() {
'''
tag Tool {
Powered
Colored
}
@Tool(Colored, Powered, Powered)
class Lamp
''' => [
parse
.assertError(
LanguagePackage.Literals.TAG_REFERENCE,
FlaxValidator.DUPLICATE_ELEMENT,
StringUtils.ordinalIndexOf(it, 'Powered', 2),
'Powered'.length,
'Duplicate argument "Powered" for tag "Tool" for class "Lamp"'
)
]
}
[Updated on: Tue, 03 January 2017 23:12] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.03514 seconds