Scope issue: ListScope is not a subtype of Scope

Hi all,
I try to define my first constraint that makes sure that already used references are filtered from the completion list. I follow the example of the introductory video #3: Constraints, where the same thing is done for the Kaja language.
here is my attempt:

concepts constraints ConceptWithRef{ 
 ...
   
  link {switch} 
    referent set handler:<none> 
    scope: 
      (exists, referenceNode, contextNode, containingLink, linkTarget, operationContext, enclosingNode, model, position, contextRole)->Scope { 
        final sequence<node<ConceptDef>> conceptSeq = model.roots(ConceptDef).
            where({~conceptDef => enclosingNode.ancestor<concept = ParentOfConceptWithRefs>.descendants<concept = ConceptWithRef>.
            where({~it => it != contextNode; }).select({~it => it.conceptRef; }).all({~it => it != conceptDef; }); }); 
        new ListScope(conceptSeq) { 
          public string getName(node<> child) { 
            child : INamedConcept.name; 
          } 
        }; 
      } 
    presentation : 
      <no presentation> 
  ; 
      
}
prettyPrint();

The structure of my language is like so:
Root
|_
|  listOfConceptDefs : ConceptDef [1..n]
|_
   parentOfConceptWithRefs : ParentOfConceptWithRefs [1]
   |_
      conceptRef : ConceptRef [0..n]
     |_
        (ref to)ConceptDef

I get an error: "ListScope$anonymous is not a subtype of Scope"
ListScope extends Scope, however.
So, what am I missing?

Thanks,
Robert
5 comments
I got it to compile by wildly importing scope-related models, stubs, and languages and then pressing the magical "perform Quick Fixes" button. Looking at what is imported now I wonder how on earth I should be able to figure that out by myself?

Also: my list of references in my editor is completely empty now, although I defined plenty of ConceptDef instances...? Is there anything wrong with my scope creation?
0
I suspect there must be something fundamentally wrong in the code somewhere, since the only model that you should need to import into the constraints model is jetbrains.mps.scopes - hit Control + R and select ListScope.
The type-system error that you are reporting also looks quite weird to me, provided you are defining a "reference" scope, not the deprecated "search" scope. If it is possible to share the project, I'll be happy to have a look.

Vaclav
0
Thanks for the reply and the tip with Ctrl-R. I'm new to MPS and just brute forcing myself through the different aspects at that point. Can you point me to a place where those handy Hotkeys are listed?

I probably started out with too big of a language, but the language did already exist and creating the concept structure was pretty straight forward.

Again, I am at a point where I can build the project, but my basket/code completion list/however-it-is-called-in-MPS is empty. I should probably learn how to debug something like code above ;).

Anyways, in case you do want to take a look at the project, you can find it here: https://dl.dropboxusercontent.com/u/10307034/DialogScript.zip
The concepts in question are "SwitchDef", which is the concept that is referenced in "SwitchRefWithValue".

PS: I can only ask 1 question per day as a newbie? That's harsh!
0
I recommend that you go through the Fast Track tutorial (https://confluence.jetbrains.com/display/MPSD32/Fast+Track+to+MPS), perhaps starting with the "Projectional Editing Trips and Tricks" chapter (https://confluence.jetbrains.com/display/MPSD32/Fast+Track+to+MPS#FastTracktoMPS-Step6-Projectionaleditingtipsandtricks).

The https://confluence.jetbrains.com/display/MPSD32/Commanding+the+editor page lists the essential keyboard shortcuts that will make your life with MPS easier.

In your concrete example of a constrain you are using model.roots() on a concept that is not rootable (SwitchDef), and so the query will always return an empty collection. You were probably looking for the model.nodes() query method.

link {switch} 
  referent set handler:<none> 
  scope: 
    (exists, referenceNode, contextNode, containingLink, linkTarget, operationContext, enclosingNode, model, position, contextRole)->Scope { 
      final sequence<node<SwitchDef>> switchDefSeq = model.roots(SwitchDef).where({~switchDef => enclosingNode.containing root.descendants<concept = SwitchRefWithValue>.where({~it => it != contextNode; }).select({~it => it.switch; }).all({~it => it != switchDef; }); }); 
      new ListScope(switchDefSeq) { 
        public string getName(node<> child) { 
          child : INamedConcept.name; 
        } 
      }; 
    } 
  presentation : 
    <no presentation> 
;
prettyPrint();

Vaclav
0
Hi Vaclav,
thanks, that did the trick.
I will study the links you provided, thanks.
Robert
0

Please sign in to leave a comment.