7 Mar 2012

Add line number to your persistent XMI of DSL

I am developing a DSL using xtext. The DSL program is serialised as a XMI file. The final aim of this project is to transform the DSL program to the input of an analysis tool, and back annotate the analysis result to the DSL user. Obviously the first thing the DSL user want to see is the line number that results the analysis tool to report error. The xtext tutorial does not help a lot. After several hours working, this is my final solusion.

1. Update the Ecore model if the xtext project imports an existing Ecore model. If the Ecore model is generated, you can write a post processor, but it is suggested by xtext document that if you need to modify the Ecore model probably you need to import it rather than generate it.
In my case, I add attribute "lineNumber" to the model Statement that needs a line number.

2. Find the generated class StatementImpl.java. There should be a getLineNumber() method. Modify it to

public int getLineNumber() {
return NodeModelUtils.getNode(this).getStartLine();
}

It is possible that org.eclipse.xtext.nodemodel.util.NodeModelUtils cannot be import. Remember to add xtext plugin dependency to the plugin.xml
NodeModelUtils.getNode(EObject ob) returns the node that is directly associated with the given object by means of an EMF-Adapter.
getStartLine() simply return the line number that the syntax elements begins.

3. Change StatementImpl.eIsSet() method. Make sure when the feature ID is line number attribute, alway return true so that attribute can always be serialised.

4. Do not forget to change @generated to not generate.

Thanks to:
This helps a lot, but the api has been changed since xtext 2.0. There is no NodeUtil class. The original NodeUtil class is divided to INode and NodeModelUtils class.