I have troubles with understanding how i can influence the scoping. assume i have simple grammar:
Model:
def = DefVarList
(use = UseList)?
;
DefVarList:
name = 'def' '{' (list += DefVar)* '}'
;
DefVar:
name = ID ';'
;
UseList:
name = 'use' '{'
(list += UseVar)*
'}'
;
UseVar:
name = [DefVar] ';'
;
of course, writing something like
def { qwerty; }
use { qwerty; }
results error, because one couldn't resolve a reference. So i went to ScopeProvider class and rewrite it:
public class TestgrammarScopeProvider extends AbstractTestgrammarScopeProvider{
public IScope scope_UseVar_name(UseVar v, EReference ref) {
Model m = (Model)v.eContainer().eContainer();
return Scopes.scopeFor(m.getDef().getList());
}
}
This doesn't working. It doesn't even call this function. What am i doing wrong?
P.S. i know about inserting fragment line in my mwe2 file, but i wonder why this program doesnt call this function.
You are using a cross reference as an identifier in UseVar. I changed that to
UseVar: ref=[DefVar] ';'
Then this xtend snippets works for your DSL.
override IScope getScope(EObject context, EReference ref){
if(context instanceof UseVar && ref == USE_VAR__REF){
val model = context.getContainerOfType(Model)
val defVarList = model.def.list
return Scopes::scopeFor(defVarList)
}
return IScope::NULLSCOPE
}
Am also assuming this is just a starting demo to get your project going but you might consider removing some of the syntactic noise such using this for a list instead
List items+=rule (',' items+=rule)*;
or perhaps removing the curly braces too (but you may want nested blocks later in which case you may need them). Only you can tell but its worth considering.