Ограничить область действия Xtext папкой

#xtext #scoping

#xtext ( текст ) #определение области применения

Вопрос:

При наличии двух моделей Xtext в одном проекте, но в разных папках, использующих одни и те же имена (ID) для разных объектов, область видимости работает не так, как я хочу. Как я могу ограничить область действия внутри одной папки, а не всего проекта? Пример:

грамматика:

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

структура папок:

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

person1.mydsl содержит персону («Джейн»), person2.mydsl также содержит персону («Джейн») и приветствие.mydsl содержит приветствие («Привет, Джейн!»), ссылающееся на персону в person1.mydsl вместо персоны в person2.mydsl.

В документации указано, что я должен использовать StateBasedContainerManager, но я не понимаю, где и как.

Комментарии:

1. в вашем случае вы должны реализовать / настроить IGlobalScopeProvider и отфильтровать глобальную область по умолчанию (DefaultGlobalScopeProvider) для фильтрации по тому же префиксу в uri.

2. В какой момент я могу добавить свой фильтр? Я вижу только возможность редактировать область MyDslScopeProvider (extends AbstractMyDslScopeProvider) действия. Вероятно, мне придется изменить, какой IGlobalScopeProvider вводится в XtextScopeProvider?

3. как я уже сказал: org.eclipse.xtext.scoping. IGlobalScopeProvider.getScope(ресурс, ссылка, предикат<IEObjectDescription>)

4. да, вопрос был о том, как указать моему плагину xtext использовать мой измененный IGlobalScopeProvider, но я нашел его и отвечу на свой вопрос, спасибо за вашу помощь

Ответ №1:

Благодаря @Christian и this я нашел решение. Итак, сначала добавляем фильтр в 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);
    }
}
 

а затем сообщить моему модулю времени выполнения использовать вместо этого моего провайдера

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

Комментарии:

1. в полной реализации вы бы и ваш предикат с тем, который передается методу с Predictates.and