1
votes

I'm not quite sure I understand how the scoping process works in xText, working with several model files. Referencing within one file works fine, just having to specify a rule along the lines of ref=[referencedObject | ID], I can get the auto completion to work out of the box ; however, I can't seem to access any EObject in another file. The information I found is not very explicit about that case, and I don't really understand what I am supposed to do to make it work...

I tried referencing by QualifiedName, but I simply don't get where I'm supposed to make the reference actually happen - how my separate files can access each other.

EDIT : code

File returns File:
    UIRule | EventRule
;

QualifiedName:
    ID ('.' ID)*
;

/* First file */
UIRule returns Ui:
    {Ui}
    "ui"
    (screens+=ScreenRule (screens+=ScreenRule)*)?
;

ScreenRule returns Screen:
    name=ID "as" "screen"
    '{'
        (elements+=GUIElementRule )*
    '}'
;
GUIElementRule returns Button:
    name=ID "as" "element"
;


/* Second file */
EventRule returns Event:
    {Event}
    "event"
    rules+=RuleRule*
;

RuleRule returns Rule:
    "on" "{" on=ButtonPressRule "}"
    "do" "{" do=ActionRule "}"
;

ButtonPressRule returns Pressed:
    "press" "[" source=[GUIElement | QualifiedName] "]"
;
ActionRule returns Open:
    "open" "[" screen=[Screen | QualifiedName] "]"
;
1

1 Answers

0
votes

There is no difference between linking within one file and linking between different files: In both cases the link destination is lookup up in the index. So usually there is no distinction between these two cases. BTW, the relevant sections in the manual are Linking and (especially) Scoping.

I tried referencing by QualifiedName, but I simply don't get where I'm supposed to make the reference actually happen - how my separate files can access each other.

The relevant sections of your grammar should look like this (Please note the caps in ReferencedObject):

ReferencedObject:
    name=ID /* more stuff */;

Something:
    name=ID ref=[ReferencedObject | QN];

QN: 
    ID ('.' ID)*;

As long as ReferencesObject has a name and each of its containers also has a name attribut you should be done. I'm assuming that you did not modify the ScopeProvider class of your language.


EDIT:

The given grammar is not correct and not self contained.

  • The first rule cannot be a datatype rule like QualifiedName. The grammar would not compile with this.

  • NavigationRule is not used and ActionRule is unknown. I assume that for the sake of example ActionRule can be replaced with NavigationRule.

  • The complete EventRule part is not used. So either the top-level rule is missing (see first point) OR the grammar simply would not know how to parse a file with Event-Rules. Of course scoping and crossreferencing in an unparsable file is difficult ;-)

So: After fixing The NavigationRule / ActionRule and using the following rule as the first rule I can generate the plugins with not more modification using the standard "MyDsl" example from Xtext:

File:
    ui = UIRule | event = EventRule
;

Then I can start the editor and write these two files (with code-completion and correct proposals in file 2):

File 1:

S1 as screen { 
    S1E1 as element 
    S1E2 as element
}

S2 as screen { 
    S2E1 as element
    S2E2 as element
}

File 2:

on { press [ S1.S1E1 ] }
do { open [ S2 ] }

In the second file the crossreferences are resolved: I can shift-click on S2 and on S1.S1E1 and Xtext jumps to the definition.

So if this does not work for you then you should start with a clean project OR provide a SSCCE Example which demonstrates your problem properly.