Name Provider
The name provider is responsible for giving a name to an object so that it may be referenced. The following uses naming:
- Cross referencing, such as when using the bracket syntax like: [Type|ID]
- Used as default in label provider (affects outline view, hyperlinks and content proposals,)
The default behavior uses the following conventions:
If an object has a feature with a string-type, whose name is 'name', the default name provider implementation will use the value of that feature for calculating the name of an object.
Magic Names
Generally names can be anything except the following have special meaning:
Syntax Element | Means |
---|---|
name | Supports cross referencing. If an object has a feature with a string-type, whose name is 'name', the default name provider implementation will use the value of that feature for calculating the name of an object. |
importURI | URI of a model file whose objects should be made visible. Supports URI import of a particular file like this: Where STRING is a rule with string value |
importedNamespace | A namespace import normally looks as follows: Import: 'import' importedNamespace=FqnWithWildCard; FqnWithWildCard: Fqn('.*')?; Fqn:ID('.'ID)* |
There is more information about how these are used on this page also on this Itimus blog.
question
Why does this grammar work?
Import returns EuclidImport : 'import' ( importedNamespace=QualifiedName | importedNamespace=QualifiedNameWithWildCard) ';'? ;
But not this?
Import returns EuclidImport : 'import' importedNamespace=QualifiedName ('.' '*')? ';'? ;
Qualified Names
When we build an EMF model using xtext then there is a natural heirarchy (tree structure). When a rule is used within another rule this generates a containment relationship. We can therefore specify any object incidence of an in the runtime model by using its qualified name. This is a string formed from the names of the objects, starting at the model root and ending at the object instance required. These names can be separated with a dot '.' to form a single string. |
If we specify the QualifiedNamesFragment in the mwe2 file:
fragment = exporting.QualifiedNamesFragment {}
and we have a rule like this:
QualifiedName: ID ('.' ID)*;
in our grammar then we can identify any object in the files containment heirchy by specifying its heirchy of names separated by dots '.'. Provided that each level has a name.
For a quide to value convertors see the screencast on the Boris Brodski site.
Runtime Issues
We have looked at how QualifiedNames are defined in the grammar file and so get into the Ecore model. We now need to know how these are used at runtime when our DSL is working and how this can be used as a destination for our non-containment links. |
I think it would help with debugging programs if there were a utility that could be run in the runtime UI(second instance of Eclipse) so that, when the user clicked on an object, its qualified name were dispayed if it had one.
Since I can't find such a tool, I have appropriated the 'outline view' for such a purpose by setting the labels to the qualified name. Obviously this is not the best solution since we probably wan't to use the outline view for other things. It would be good if the developers could provide a view for this purpose. | package com.euclideanspace.importTest.ui.labeling; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider; import org.eclipse.xtext.naming.IQualifiedNameProvider; import org.eclipse.xtext.naming.QualifiedName; import org.eclipse.xtext.xbase.ui.labeling.XbaseLabelProvider; import com.google.inject.Inject; /** * Provides labels for a EObjects. */ public class MyTestLabelProvider extends XbaseLabelProvider { @Inject public MyTestLabelProvider(AdapterFactoryLabelProvider delegate) { super(delegate); } @Inject private IQualifiedNameProvider nameProvider; public String text(EObject eObject) { QualifiedName qn = nameProvider.getFullyQualifiedName(eObject); if (qn==null) return "no qualified name"; return qn.toString(); } } |
Other Naming Conventions
ID | |
INT | |
DOUBLE | |
STRING | enclosed in single or double quotes |
Simple Test Example
So lets build a very simple xtext project to experiment with naming. I just created an xtext project, entered the grammar below and generated the project |
|
grammar com.euclideanspace.naming.Example with org.eclipse.xtext.common.Terminals generate example "https://www.euclideanspace.com/naming/Example" Model: a+=A*; A: 'a' name=ID ('{' b+=B* '}')?; B: 'b' name=ID; |
|
When we start this program up in a new instance of eclipse we can enter in various names such as the input text below. | |
a tom a dick a tom a dick {b harry b tom} |
There does not appear to be any restriction on the names, for instance, there is nothing to stop us from using duplicate names.
As you can see, the names are used to represent the elements in the outline view.
If we want to force names to be unique then we need to uncomment the following line in the mwe2 file in the JavaValidatorFragment . Then regenerate: | |
composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" | |
Now names are forced to be unique. But only within a given object, we can reuse the same name across two different objects. We can see here that the name 'tom' is used in object 'a' and again in object 'b' without error. It can also be reused in different outer objects. Its only duplications within the same object that are prevented. |
So to summarise, the checking of names depends on the fragments included in the mwe2 file:
Fragments Included | Effect on Naming |
---|---|
exporting.SimpleNamesFragment | duplicates allowed, no '.' allowed in names |
exporting.QualifiedNamesFragment | duplicates allowed |
exporting.SimpleNamesFragment |
duplicates prevented anywhere within the whole file. |
exporting.QualifiedNamesFragment
|
duplicates prevented only within a given object. |
Further Reading
- Go on to scoping on this page.
- There is more about cross-referencing, on this page, where the above example is continued.
- For more information about importing from native java code go on to this page.
- This itemis blog has more information about this topic.