|
|
|
|
Re: Ensure type safety for Xtext grammar [message #1224991 is a reply to message #1223198] |
Sat, 28 December 2013 10:43 |
Sebastian Kämpfer Messages: 3 Registered: December 2013 |
Junior Member |
|
|
So I decided to use Scoping over qualified names. The reasons for that I'll explain in this post.
A tutorial which I found very useful to begin with is this Xtext screencast:
(http://)xtextcasts.org/episodes/17-restricting-scope
The problem with qualified names here is that I could easily do something like this:
Assignment :
'set' property=[Entity|QualifiedName] '=' value=STRING
;
-------------
Entity Foo {
var name : String
}
set Foo.name = 'bar' // works with QNames
but not for "instances" like I need to:
make Foo instanceOfFoo
set instanceOfFoo.name = 'bar' // does not work with QNames
Solution:
If my grammar looks like this:
Root :
entities=Entity*
instances=Instance*
assignments=Assignment*
;
Entity :
'Entity' name=ID ('extends' superType=[Entity])? '{'
properties=Property*
'}'
;
Property :
'var' name=ID ':' type=[Type]
;
Instance :
'make' entity=[Entity] name=ID
;
Assignment :
'set' instance=[Instance]'::'property=[Property] '=' value=STRING
;
a code like this:
Entity Foo {
var name : String
}
make Foo instanceOfFoo
set instanceOfFoo::name = 'bar' // property 'name' is out of scope for this assignment
would not be possible since a cross reference to the entity's property 'name' is out of scope in the specific assignment.
Solution for this is to customize a scope provider which may look like this:
def IScope scope_Assignment_property(Assignment assignment, EReference eReference) {
var entity = assignment.instance.entity
if(entity.superType != null)
Scopes::scopeFor(entity.properties,scope_superType_property(entity.superType))
else
Scopes::scopeFor(entity.properties)
}
def IScope scope_superType_property(Entity entity){
Scopes::scopeFor(entity.properties)
}
This 'imports' the properties defined in the scope of the application of the Entity-Rule into the scope of the application of the Assignment-Rule. In this example I also applied an outer scope (second method) which imports the properties of a parent class :
Entity Foo {
var name : String
}
Entity Bar extends Foo {
var id : Int
}
make Bar instanceOfBar
make Foo instanceOfFoo
set instanceOfFoo::name = 'Name'
set instanceOfBar::name = 'TestMe' // works as well
Regards,
Sebastian
[Updated on: Sat, 28 December 2013 10:50] Report message to a moderator
|
|
|
Powered by
FUDForum. Page generated in 0.03653 seconds