Hello everyone,
I wrote an Xtext grammar for a small imperative programming language called PSimple. PSimple is the input language of a static analysis tool called PInterproc. My goal is to automatically translate as much as possible of a given Matlab program into a PSimple program and feed it to PInterproc.
Matlab programs are represented as models of a preexisting metamodel (GeCoS CDFG).
My grammar refers to metaclasses from this meta model and from another (lightweight) one used to store information that cannot be directly mapped onto the GeCoS metamodel.
Parsing a PSimple program works just fine. However, I'm struggling with the serialization of a model to its textual representation. The problems I'm seeing are:
- Some features in the GeCoS metamodel are non-transient, but have no corresponding assignment in my grammar. I can (seemingly) overcome this problem by disabling validation, but I'd prefer to tell Xtext to ignore features that have no textual representation. Is there a way to do this ?
I really cannot modify the metamodel, so, setting "transient" to "true" is not an option.
- PSimple features user-defined and built-in types (int and real). Variables are declared like this:
Symbol returns core::Symbol:
name=ID ':' type=[types::Type]
;
The meta-classes Symbol and Type come from the GeCos metamodel.
After investigating various approaches for the support of built-in types, I decided that the easiest way was to instantiate new Type's on-the-fly in the linking service.
package fr.irisa.cairn.interproc.simple.modules;
import gecos.core.Symbol;
import gecos.types.*;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.xtext.linking.impl.DefaultLinkingService;
import org.eclipse.xtext.nodemodel.INode;
public class SimpleLinkingService extends DefaultLinkingService {
private BaseType intType;
private BaseType realType;
@Override
public List<EObject> getLinkedObjects(EObject context, EReference ref, INode node) {
List<EObject> res = super.getLinkedObjects(context, ref, node);
if (context instanceof Symbol && ref.getFeatureID() == gecos.core.CorePackage.SYMBOL__TYPE) {
if (node.getText().equals("int")) {
if (intType == null) {
intType = TypesFactory.eINSTANCE.createBaseType();
intType.setType(Types.INT);
context.eResource().getContents().add(intType);
}
return Collections.singletonList((EObject)intType);
} else if (node.getText().equals("real")) {
if (realType == null) {
realType = TypesFactory.eINSTANCE.createBaseType();
realType.setType(Types.FLOAT);
context.eResource().getContents().add(realType);
}
return Collections.singletonList((EObject)realType);
}
}
if (res.size()==0) {
System.out.println("Resolution failed for node: "+node.toString());
}
return res;
}
}
But when I launch the serialization it fails with this error:
No EObjectDescription could be found in Scope Symbol.type for BaseType.
What am I doing wrong and, most importantly, what are my options here ?
Thanks in advance,
Gaël