Archive

Posts Tagged ‘IQualifiedNameProvider’

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 IQualifiedNameProviderSimpleNameProvider 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
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;
	}

}
Categories: Xtext Tags: ,