Проблемы перекрестных ссылок в Xtext
Я использую Xtext 2.10.0 и, кажется, есть некоторые проблемы с перекрестными ссылками. Упрощенно, моя грамматика (с org.eclipse.xtext.common.Terminals) следующая:
Model:
package=Package
dtos+=DTO*;
Package:
'package' name=FQN;
FQN:
ID ('.' ID)*;
DTO:
'dto' name=ID ('extends' extendedDTO=[DTO|FQN])? '{' '}';
Чтобы обеспечить правильное квалифицированное имя для DTO, я реализовал собственный DefaultDeclarativeQualifiedNameProvider, который собирает квалифицированное имя на основе имени пакета и имени DTO.
Теперь я создаю первый DTO в файле "base.dto":
package base
dto BaseDTO {}
Во втором файле "mydto.dto" я создаю второй DTO:
package mydto
dto MyDTO extends base.BaseDTO {}
Часть "base.BaseDTO" даже предлагается механизмом автозаполнения. Тем не менее, Eclipse помечает эту часть как ошибку и говорит: "Не удалось разрешить ссылку на DTO" base.BaseDTO ".". Что я должен изменить, чтобы разрешить эту ссылку?
2 ответа
Проблема заключалась в том, что у моего оригинального NameProvider был следующий метод (где "qualPackageName" является методом расширения, предоставляющим имя пакета):
def qualifiedName(DTO dto) {
val packageName = dto.qualifiedPackageName
val dtoName = dto.name
val qualifiedName = QualifiedName.create(packageName, dtoName)
qualifiedName
}
Однако имя пакета является полностью определенным именем, и кажется, что его необходимо разделить на отдельные сегменты:
static val PACKAGE_SEPARATOR = '\\.'
def qualifiedName(DTO dto) {
val packageName = dto.qualifiedPackageName
val packageNameSegments = packageName.split(PACKAGE_SEPARATOR)
val dtoName = dto.name
val segments = packageNameSegments + #[dtoName]
val qualifiedName = QualifiedName.create(segments)
qualifiedName
}
С измененным NameProvider, кажется, все работает идеально.
Здесь я мой NameProvider Impl
class MyDslNameProvider extends DefaultDeclarativeQualifiedNameProvider {
def QualifiedName qualifiedName(DTO dto) {
val model = EcoreUtil2.getContainerOfType(dto, Model)
val packageName = converter.toQualifiedName(model.package.name)
val result = packageName.append(dto.name)
result
}
}