Как настроить Xtext mwe.Reader для заполнения корневого элемента в слоте
Я использую Xtext 2.0 с MWE 1 и XPand, но я думаю, что проблема для MWE 2 и XTend точно такая же.
Мой грамматик Xtext выглядит следующим образом (отрывок):
grammer org.test.Test with org.eclipse.xtext.common.Terminals
generate test "http://www.test.org/test/Test
Model :
"COMMON STUFF"
"{"
(formatterDefs+=FormatterDef)*
"}"
...
FormatterDef : "Formatter" name=ID ":" formatter=STRING;
Когда я использую это определение Mwe (выдержка):
<component class="org.eclipse.xtext.mwe.Reader" path="${project.src.directory}/xtext/model/" >
<register class="org.test.TestStandaloneSetup"/>
<load slot='formatterDefs' type='FormatterDef'/>
</component>
<component class="org.eclipse.xpand2.Generator">
<metaModel class="org.eclipse.xtend.typesystem.emf.EmfRegistryMetaModel"/>
<expand value="templates::Formatter::formatterTxt FOREACH formatterDefs"/>
</component>
Итак, слот formatterDefs
заполнен всем FormaterDef
, а затем это используется для шаблона, и каждая мысль работает нормально.
Но у меня есть несколько шаблонов, для которых требуется корневой элемент модели с именем Model
в грамматике. Поэтому я попытался использовать
<load slot='formatterDefs' type='FormatterDef'/>
а также
<expand value="templates::Main::main FOREACH model"/>
вместо.
Но тогда я получаю это предупреждение:
org.eclipse.xtext.mwe.SlotEntry - Не удалось найти экспортируемый элемент типа "Модель" -> Слот "модель" пуст.
И слот содержит пустой список.
Итак, мой вопрос: что мне нужно сделать, чтобы получить рут Model
в мои шаблоны?
4 ответа
Я имел в виду что-то вроде
public class MyDslNameProvider extends DefaultDeclarativeQualifiedNameProvider {
QualifiedName qualifiedName(Model m) {
return QualifiedName.create(m.eResource().getURI().toString());
}
}
public class MyDslRuntimeModule extends
org.xtext.example.mydsl.AbstractMyDslRuntimeModule {
@Override
public Class<? extends IQualifiedNameProvider> bindIQualifiedNameProvider() {
return MyDslNameProvider.class;
}
}
Вы можете настроить IQualifiedNameProvider, чтобы дать модели имя.
~ Christian
Наверное, лучший способ вставить текст {Model}
только в начале правила, чтобы обеспечить создание.
Решением было добавить идентификатор в определение грамматики модели.
Model : name = ID
"COMMON STUFF"
"{"
(formatterDefs+=FormatterDef)*
"}"
Я понимаю, что ранее не было существующего элемента Model, поэтому после добавления идентификатора необходимо создать элемент Model, содержащий идентификатор.
Как бы то ни было, есть лучшее решение - я приму его, как только оно будет опубликовано.