I try to show a minimal working example that describes my problem:
Grammar
This is the xtext
grammar I created for this example. (The real grammar of course is much more complex and also involves an advanced expression-language)
grammar org.example.dsl.DSL with org.eclipse.xtext.common.Terminals
generate dsl "http://www.example.org/dsl/DSL"
Model:
elements+=Declaration*
;
QualifiedName:
ID ('.' ID)*
;
Declaration:
SimpleTypeDeclaration |
SectionDeclaration |
FieldDeclaration
;
SimpleTypeDeclaration:
"type" name=ID "=" primitive=IntegerType
;
IntegerType
{IntegerType} "int"
;
SectionDeclaration:
"section" name=ID "{"
elements+=FieldDeclaration*
"}"
;
TypeDeclaration:
SimpleTypeDeclaration |
SectionDeclaration
;
FieldDeclaration:
name=ID ":" type=[TypeDeclaration|QualifiedName] ("=" value=ValueExpression)?
;
ValueExpression:
FieldReference |
SimpleValue
;
FieldReference:
ref=[FieldDeclaration|QualifiedName]
;
SimpleValue:
{SimpleValue} "sentinel"
;
Example-Code in Example-Language
This is some example code in the language I described above.
type Foo = int
section A {
foo: Foo = sentinel
}
section B {
a: A
// here I want to assign the value of a subfield of `a`
// to fubar
fubar: Foo = a.foo // crucial point
}
Global Index of the Example-Code snippet
The default Indexer of the Example-Code snippet would generate the following global-scope index for referencing:
[Foo, A, A.foo, B, B.a, B.fubar]
So with the correct scope I would be able to reference all those objects by these identifiers in my code on reference-resolution.
But the crucial point
in the code snippet will not be resolved, because B.a.foo
respectively a.foo
will not be in the index.
What I thought of and tried so far (incomplete solutions)
I thought of customizing the Index, so that it would additionally put
B.a.foo
into the index.- but that would pollute the index with potentially so many unnecessary resource URIs that I never would want to be referencing from the global scope.
- (e.g. I just want to be able to reference a fields subfields from within the section I'm referencing it from)
Create a new Rule in the grammar called
Selection
=> make qualified selection of fields explicit by providing a customScopeProvider
. But there are some Problems I encountered:- If I still provide the possibility to reference everything via
QualifiedName
s the grammar and resolution always think it is a typereference as before and will not ask my custom scopeprovider to provide the reference for theSelection
rule, which overloads the dot-operator (.
) - If I remove the referencing mechanism
[TypeDeclaration|QualifiedName]
replacing it with a[TypeDeclaration|ID]
I would have to customize the scoping for every base type and subreference and would not leverage the powerful default qualified-name-resolution of xtext.
- If I still provide the possibility to reference everything via
My Question now
Does anybody know about a standard or best solution to the problem I descibed?