Xtext 2.0 come with a change to the IQualifiedNameProvider interface. This interface is used to calculate a name for EObjects. The Name is used in Xtext’s index, for cross referencing and much more.
public interface IQualifiedNameProvider extends Function<EObject, QualifiedName> {
QualifiedName getFullyQualifiedName(EObject obj);
}
Here we see the API change: There is a rename of the getQualifiedName
method to getFullyQualifedName
. In Xtext 1.0.x the qualified name was a simple String, now it is a wrapper class that holds the segements of the qualified name.
There are two default implementations for a IQualifiedNameProvider
: SimpleNameProvider
and DefaultDeclarativeQualifiedNameProvider
. Consider we have a grammar like
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Package:
"package" name=ID "{"
elements+=Element*
"}"
;
Element:
"element" name=ID
;
and a sample model like
package TestPackage {
element A
element B
}
Then with SimpleNameProvider
we would have following qualified names.
TestPackage
for the packageA
andB
for the elements
And with DefaultDeclarativeQualifiedNameProvider
we would have following qualified names.
TestPackage
for the packageTestPackage.A
andTestPackage.B
for the elements
Both Providers take the name EAttribute of our Package and Element to do the calculation. The DefaultDeclarativeQualifiedNameProvider
uses the Elements parents qualified name too. (a fully qualified name ;-))
But it won’t work e.g. if our grammar would look like
grammar org.xtext.example.mydsl.MyDsl with org.eclipse.xtext.common.Terminals
generate myDsl "http://www.xtext.org/example/mydsl/MyDsl"
Package:
"package" name=ID "{"
elements+=Element*
"}"
;
Element:
"element" id=ID
;
with Element
having and id and not a name. We can easily change this by creating and binding our own IQualifiedNameProvider
e.g. by extending DefaultDeclarativeQualifiedNameProvider
package org.xtext.example.mydsl;
import org.eclipse.xtext.naming.DefaultDeclarativeQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.xtext.example.mydsl.myDsl.Element;
import org.xtext.example.mydsl.myDsl.Package;
public class MyDslQNP extends DefaultDeclarativeQualifiedNameProvider{
QualifiedName qualifiedName(Element e) {
Package p = (Package) e.eContainer();
return QualifiedName.create(p.getName(), e.getId());
}
}
We simply write a method qualifiedName that is called from the polymorpthic dispatcher when calculating the name of an Element
package org.xtext.example.mydsl;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
/**
* Use this class to register components to be used at runtime / without the Equinox extension registry.
*/
public class MyDslRuntimeModule extends org.xtext.example.mydsl.AbstractMyDslRuntimeModule {
@Override
public Class<? extends IQualifiedNameProvider> bindIQualifiedNameProvider() {
return MyDslQNP.class;
}
}