Cross-References issues in Xtext

437 views Asked by At

I am using Xtext 2.10.0 and seem to have some issues with cross-references. Simplified, my grammar (with org.eclipse.xtext.common.Terminals) is the following:

Model:
    package=Package
    dtos+=DTO*;

Package:
    'package' name=FQN;

FQN:
    ID ('.' ID)*;

DTO:
    'dto' name=ID ('extends' extendedDTO=[DTO|FQN])? '{' '}';

In order to provide a correct qualified name for the DTOs, I implemented an own DefaultDeclarativeQualifiedNameProvider, which assembles a qualified name based on the name of the package and the name of the DTO.

Now I create a first DTO in a file "base.dto":

package base

dto BaseDTO {}

In a second file "mydto.dto" I create a second DTO:

package mydto

dto MyDTO extends base.BaseDTO {}

The part "base.BaseDTO" is even suggested by the autocompletion mechanism. However, Eclipse marks this part as an error and says "Couldn't resolve reference to DTO 'base.BaseDTO'.". What do I have to change in order to resolve this reference?

2

There are 2 answers

0
Christian Dietrich On

Here i my 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
    }

}
0
nils On

The issue was, that my original NameProvider had the following method (where "qualifiedPackageName" is an extension method delivering the name of the package):

def qualifiedName(DTO dto) {
  val packageName = dto.qualifiedPackageName
  val dtoName = dto.name

  val qualifiedName = QualifiedName.create(packageName, dtoName)

  qualifiedName
}

However, the package name is a fully qualified name and it seems that it is necessary to split it into the single segments:

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
}

With the modified NameProvider, everything seems to work perfect.