#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