IQualifiedNameProviders in Xtext 2.0
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 package
- A and B for the elements
And with DefaultDeclarativeQualifiedNameProvider we would have following qualified names.
- TestPackage for the package
- TestPackage.A and TestPackage.B for the elements
DefaultDeclarativeQualifiedNameProvider uses the Elements parents qualified name too. (a fully qualified name
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
;
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;
}
}
Hello Christian
Thank you so much for this great expression
Look forward to read more about Xtext 2.0 on your blog
BR
Caner
well written und precise! gch
Hi Chrisitan,
thanks allot. Your blog help avoiding a lot of trouble casued by ‘out-of-date’.
One needs to update the XText-Grammar docu which still describes the frist “ID” terminal rule used for as key for linking. As described in your blog it’s always just the “name” feature if available like hard coded in the DefaultDeclarativeQualifiedNameProvider.
The ‘out-of-date’ docu section can be found here:
http://www.eclipse.org/Xtext/documentation/2_1_0/020-grammar-language.php#cross_reference
Hi, i guess the doc is talking only about the left (grammar) side of cross references and wants to state that ref=[Type] is short for ref=[Type|ID]