Results for category "Xtext"

2 Articles

Processing annotations in Xtext and receiving “Could not find field…”

As I mentioned in my last post the current Xtext DSL I am working on provides annotation support. Every artifact generator plug-in can provide additional annotations which influences the generation process of different artifacts. My unit tests were all green but at runtime in Eclipse/OSGi environment I received the following error:

Caused by: java.lang.NoSuchFieldException: Could not find field de.schakko.mydsl.artifact.extension.EXTERNAL_OUTPUT
at org.eclipse.xtext.xbase.interpreter.impl.XbaseInterpreter.featureCallField(XbaseInterpreter.java:691)

I debugged the source code and noticed that my main plug-in (the .ui project of my Xtext DSL) throws an inner ClassNotFoundException as de.schakko.mydsl.artifact.extension is not available through the OSGis DefaultClassLoader. The reason for this error was obvious: de.schakko.mydsl parses the model of the DSL and maps every XAnnotation to the corresponding JVM type. The parsing process is triggered by de.schakko.mydsl.ui so this classloader is used. The annotation itself is inside the de.schakko.mydsl.artifact.extension.jar and can not be seen by de.schakko.mydsl.ui. Adding de.schakko.mydsl.artifact.extension to the Require-Bundle/Import-Package declartion inside de.schakko.mydsl.ui/META-INF/MANIFEST.MF was no solution, because the UI project does not know anything about the artifact generators.
I tried using the Eclipse-BuddyPolicy/Eclipse-RegisterBuddy solution, but this does not work for unknown reasons. Another option was to provide every classloader of the artifact generators to a defined extension point inside de.schakko.mydsl.ui. Not really nice.
In the end I found the DynamicImport-Package declaration of the OSGi standard. This manifest header instructs the OSGi classloader to lookup the class in the standard required and imported packages. If this fails other bundles on classpath are searched through.

Accessing the values of an annotation inside your Xtext-DSL

Today I implemented the last feature of my bachelor thesis and struggled upon a small problem: My DSL makes use of XAnnotation to annotate various grammar elements. The generators can extend the DSL by introducing new annotations which can be used for modifying the generation process of the resulting fragments. Checking, whether an annotation is present or not is easy but retrieving the value of a named parameters in a really easy way was not so obvious at first. Thankfully Xtext/Xbase provides the class XbaseInterpreter for evaulating XExpression objects on the fly. This is the helper method:

class AnnotationExtension {
	@Inject
	XbaseInterpreter interpreter;

	public Object getValue(XAnnotation annotation, String simpleName) {
		IEvaluationResult result = null;
		if (simpleName.equals("value")) {
			result = interpreter.evaluate(annotation.getValue());
		}

		if (result != null) {
			for (XAnnotationElementValuePair pair : annotation
					.getElementValuePairs()) {
				if (pair.getElement().getSimpleName().equals(simpleName)) {
					result = interpreter.evaluate(pair.getValue());
				}
			}
		}

		return (result != null) ? result.getResult() : null;
	}
}

And here is the snippet of the usage inside the DSL:

import de.schakko.rapid.artifact.fpanalysis.runtime.annotation.UseFunctionpointType
import de.schakko.rapid.artifact.fpanalysis.runtime.types.FunctionpointType

// ...

domain d5_fixture {
  @UseFunctionpointType(FunctionpointType::EXTERNAL_INQUIRY)
  process p5_custom {
  }
}