3

I am trying to custom scoping, such that if I have something like function in my language that get parameters, I want that those parameters will be visible only until there is semicolon, and out of this scope, I want it to not be visible.

I tried redefine the method getScope() in the file MyDslScopeProvider.xtend

In getScope I did something like this:

 if (EclassName=="TypedParam" && EFeatureName=="type" && contextType == "TypedParam"){
        return Scopes.scopeFor(Collections.singleton(context),IScope.NULLSCOPE)
    }

This is abviosly doesn't working (It doesn't recognize the parameters). How can I do it?

Moreover, I have another question: I tried implements methods like:

def IScope scope_<EClass name>_<EFeature name>(<context type> context, EReference)

Although I printed the names and I made sure I am writing the name correct, those method simply never called. (I copied what was printed from the following code)

class DomainmodelScopeProvider extends AbstractDomainmodelScopeProvider {
    override def IScope getScope(EObject context, EReference reference)
    {

        System.out.println("scope_" + reference.getEContainingClass().getName()
             + "_" + reference.getName()
             + "(" + context.eClass().getName() + ", ..)"
        );

        return super.getScope(context,reference);                   
    }

What am I doing wrong?

Thanks!!!

RoG
  • 411
  • 4
  • 20

1 Answers1

2

The Problem is that with Xtext 2.9+ AbstractDeclarativeScopeProvider is no longer the default superclass of YourdslScopeProvider. You are expected to override getScope(EObject context, EReference ref)and do if elsing there. Or you change the superclass manually. Btw you can use the Constants in YourdslPackage.Literalsinstead of using manual string constants.

Christian Dietrich
  • 11,778
  • 4
  • 24
  • 32
  • Thank Christian for the comment I will use getScope instead of scope_ methods. Regard to my first question, I have in my language something like function that get parameters of type Var (something like: function a(Var v)) but I want that v will be visible only in the scope of the function.. (until there is semicolon) but I don't know which parameters to send to scope::forScope (which elements and which IScope outer)? Is that something I need to do in MyDslScopeProvider or in my grammar? Thanks a lot! – RoG Jul 31 '16 at 07:02
  • I dont get that Point . You Collect the Stuff for the scope and the outer scope is iscope.nullscope in doubt – Christian Dietrich Jul 31 '16 at 08:16
  • o.k, thanks. I try to implement the getScope function that get EObject context as parameter. I tried do if elsing there, but I don't know how to do it without casting (and casting didn't work for me). How can I do it? in every "if" there is different situation, and I want to call the fields of the different types, like you did in the answer to the following question in the scope_ method (but there the parameter is very specific): http://stackoverflow.com/questions/7791871/xtext-example-of-a-scoped-object/7812650#7812650 – RoG Jul 31 '16 at 10:24
  • can you give more context please? why does casting not work? – Christian Dietrich Jul 31 '16 at 11:14
  • and as i said: if you change superclass to abstractdeclarativescopeprovider it will work with scope_ – Christian Dietrich Jul 31 '16 at 11:15
  • I have in my language Predicate that have params+=TypedParamList and TypedParamList is params+=TypedParam (',' params+=TypedParam)*; and in TypedParam I have 'type' which is cross reference, and I want to do ForScope with all the elements in the current Predicate.. I don't know how to do it because it is get in to the getScope function with context instanceof TypedParam and type is the reference – RoG Aug 01 '16 at 05:49
  • Can you please add all needed to reproduce to question – Christian Dietrich Aug 01 '16 at 06:12
  • I have this: `Predicate: 'predicate' name=ID ('(' params=TypedParamList ')')? (':' body=TemporalExpression TOK_SEMI) | ('{' body=TemporalExpression '}'); TypedParamList: params+=TypedParam (',' params+=TypedParam)*; TypedParam: (module=[Import] '.')? type=[TypeDef] name=ID; //*****and this is example of my language: ***** predicate boo (tmp counter) : next(counter)=counter+1 predicate boo2 (tmp counter) : next(counter)=counter+1 ` I want that counter would be visible only in the scope of boo and boo2 (and in both predicate the counter would be different. – RoG Aug 01 '16 at 06:33
  • yes. type is reference in TypedParam. and I have somewhere in TemporalExpression pointer=ParamReference. Now, the scoping isn't working and the reference is working. (It thinks that counter in boo and in boo2 is the same object, if I do renaming it's change both ) – RoG Aug 01 '16 at 06:48
  • then you should test if ereference=yourreference and then have a look at context and its parent hierarchy if it is a Predicate. EcoreUtil.getContainerOfType – Christian Dietrich Aug 01 '16 at 06:57
  • I tried to do like here [link](http://stackoverflow.com/questions/37664825/xtext-how-to-reference-an-element-of-an-element/37670139#37670139), but I can't do something like context.entityA.features because there are a lot of parsing rules until it's get to the rule with the reference and some of them don't have fields to do "tmp.somethingelse". so I tried to do something like in the next comment it's not working, you have an idea? – RoG Aug 01 '16 at 09:02
  • `if(reference==myreference){ val tmp = EcoreUtil2.getContainerOfType(context, Predicate); if (tmp != null) { return Scopes.scopeFor(tmp.eContents); }` – RoG Aug 01 '16 at 09:04
  • why pred.eContents? – Christian Dietrich Aug 01 '16 at 09:05
  • why not pred.paramlist.params? – Christian Dietrich Aug 01 '16 at 09:05