0
votes

When having two Xtext models in the same project but in different folders using the same names (ID) for different objects, the scoping does not work how I want it to. How can I restrict the scoping to inside one folder and not the whole project? Example:

grammar:

Model:
    persons+=Person*
    greetings+=Greeting*;
Greeting:
    'Hello' name=[Person] '!';
Person:
    'person' name=ID;

folder structure:

project
 |-folder1
   |-person1.mydsl
 |-folder2
   |-greeting.mydsl
   |-person2.mydsl

person1.mydsl contains a Person ("Jane"), person2.mydsl also contains a Person ("Jane") and greeting.mydsl contains a Greeting ("Hello Jane!") referencing the person in person1.mydsl instead of the person in person2.mydsl.

The documentation tells me to use the StateBasedContainerManager but I don't understand where and how.

1
in your case you should implement/customize IGlobalScopeProvider and filter the default global scope (DefaultGlobalScopeProvider) to filter for same prefix in uri. - Christian Dietrich
At which point am I able to add my filter? I only see the possibility to edit the scoping in MyDslScopeProvider (extends AbstractMyDslScopeProvider). I probably have to change which IGlobalScopeProvider is getting injected into XtextScopeProvider? - Marie-Saphira
as i said: org.eclipse.xtext.scoping.IGlobalScopeProvider.getScope(Resource, EReference, Predicate<IEObjectDescription>) - Christian Dietrich
yes, the question was about how to tell my xtext plugin to use my changed IGlobalScopeProvider, but I found it and will answer my question, thanks for your help - Marie-Saphira

1 Answers

0
votes

Thanks to @Christian and this I found a solution. So first adding a filter to the DefaultGlobalScopeProvider

public class MyGlobalScopeProvider extends DefaultGlobalScopeProvider {
    @Override
    public IScope getScope(Resource resource, EReference reference, Predicate<IEObjectDescription> filter) {
        filter = new Predicate<IEObjectDescription>() {
            @Override
            public boolean apply(IEObjectDescription input) {
                // implement here
            }
        };
        return super.getScope(resource, reference, filter);
    }
}

and then telling my runtime module to use my provider instead

public class MyDslRuntimeModule extends AbstractMyDslRuntimeModule {
    @Override
    public Class<? extends IGlobalScopeProvider> bindIGlobalScopeProvider() {
        return MyGlobalScopeProvider.class;
    }
}