Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Error When Serializing CrossReference
Error When Serializing CrossReference [message #1764212] Fri, 26 May 2017 17:16 Go to next message
Greg Lusk is currently offline Greg LuskFriend
Messages: 36
Registered: February 2017
Location: USA
Member
I am trying to add model elements manually in a unit test. Our grammar references another grammar, which I load using a global scope provider:

private IScope getScopeWithLibrary(Resource resource, EReference reference) {
		if (resourceDescriptionData == null) {
			synchronized (semaphore) {
				ResourceSet resourceSet = resourceSetProvider.get();
				URI uri = URI.createURI("classpath:/stdlib.stext");
				Resource stdlib = resourceSet.getResource(uri, true);
				IResourceDescription stdlibDescription = descriptionManager.getResourceDescription(stdlib);
				
				resourceDescriptionData = new ResourceDescriptionsData(Collections.singletonList(stdlibDescription));
			}
		}
		return SelectableBasedScope.createScope(super.getScope(resource, reference, null), resourceDescriptionData, reference.getEReferenceType(), false);
	}


Our unit test looks like this:

	def void testSerialization1() {
		StructuredTextFactoryImpl.init
		val model = createStructuredTextModel => [
			function = createFunctionBlock => [
				name = "F1"
				inputs = createInputsList => [
					items += createVarDeclarationInit => [
						typeName = Type_Name.NUMERIC

						variables += createPrimaryVariable => [
							name = "X"
						]
					]
				]
				outputs = createOutputsList => [
					items += createVarDeclarationInit => [
						typeName = Type_Name.BOOL
						variables += createPrimaryVariable => [
							name = "Y"
						]
					]
				]
				val var_X = inputs.items.map[variables].flatten.head
				val var_Y = outputs.items.map[variables].flatten.head
				statements += createAssignmentStatement => [
					variables += var_Y
					expression = createCall => [
						func = createIntrinsicFunction => [
							name = "COS"
						]
						args += createVariableReference => [
							variable = var_X
						]
					]
				]
			]
		]
		val resourceSet = resourceSetProvider.get
		val resource = resourceSet.createResource(URI.createURI("dummy.stext"))
		resource.contents += model

		val actual = resource.contents.head.serialize(SaveOptions.newBuilder().format.options)

}


But the Scope for IntrinsicFunction cross references can't be resolved when we run the test, and we get the following exception:

java.lang.RuntimeException: No EObjectDescription could be found in Scope Call.func for IntrinsicFunction'COS'
Semantic Object: StructuredTextModel.function->FunctionBlock'F1'.statements[0]->AssignmentStatement.expression->Call
URI: dummy.stext
EStructuralFeature: structuredText::Call.func


So my question is this: how to we provide the Scope for the Intrinsic Functions to the CrossReferenceSerializer? (I hope I am asking the right question here, and using the correct terminology).

This appears to be a resource description problem, but we have the following custom ResourceDescriptionStrategy in our project:

class StructuredTextResourceDescriptionStrategy extends DefaultResourceDescriptionStrategy {
	@Inject StructuredTextPackage pck

	override boolean createEObjectDescriptions(EObject object, IAcceptor<IEObjectDescription> acceptor) {
		switch (object.eClass) {
			case pck.structuredTextModel : { return true }
			case pck.intrinsicFunction : { 
				super.createEObjectDescriptions(object, acceptor)
				return false
			}
			case pck.functionBlock : { 
				super.createEObjectDescriptions(object, acceptor)
				return true
			}
			case pck.varDeclarationInit: {
				if (object.eContainer instanceof InputsList) {
					super.createEObjectDescriptions(object, acceptor)
					return true
				} else {
					return false
				}
			}
			case pck.unit : { 
				super.createEObjectDescriptions(object, acceptor)
				return false
			}
			default: return true
		}
	}
}
Re: Error When Serializing CrossReference [message #1764215 is a reply to message #1764212] Fri, 26 May 2017 17:28 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14669
Registered: July 2009
Senior Member
the error basically says: the object :

the scopes does not contain the object that you use inside the model

=> is your scope stuff called? does it work?

for your post i cannot see where the cross references are and what is put where ...


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error When Serializing CrossReference [message #1764216 is a reply to message #1764215] Fri, 26 May 2017 17:36 Go to previous messageGo to next message
Greg Lusk is currently offline Greg LuskFriend
Messages: 36
Registered: February 2017
Location: USA
Member
Yes, our global scope provider is called. If it helps, here is the portion of the grammar where the cross reference is specified:

Func_Call returns Call:
	func=[IntrinsicFunction] //Allow only our supported intrinsic functions
	'(' (args += Expression (',' args += Expression)*)? ')'
;

Intr_Function returns IntrinsicFunction:
	{IntrinsicFunction}
	name=ID 
	'(' (args += Intr_Function_Arg (',' args += Intr_Function_Arg)*)? ')'
	(':' returnType=Type_Name)?
	';'
;


So, if I understand things correctly, the Call object's scope doesn't understand what the IntrinsicFunction cross reference is. If that's correct, then I'm not sure how to tell if to find the scope from the root of the domain model, which is where the IntrinsicFunction definitions exist.
Re: Error When Serializing CrossReference [message #1764217 is a reply to message #1764216] Fri, 26 May 2017 17:40 Go to previous messageGo to next message
Greg Lusk is currently offline Greg LuskFriend
Messages: 36
Registered: February 2017
Location: USA
Member
For the unit test, it does appear that our ResourceDescriptionStrategy is not being called. I'm not sure what is the proper way to call it for a unit test.
Re: Error When Serializing CrossReference [message #1764219 is a reply to message #1764217] Fri, 26 May 2017 17:45 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14669
Registered: July 2009
Senior Member
func = createIntrinsicFunction => [
name = "COS"
]

this makes not sense if func is a cross reference.

then there shouldbe anther place where you do that

and here you just should set the cross reference

func = funcThatIs Defined somewhere else


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error When Serializing CrossReference [message #1764225 is a reply to message #1764219] Fri, 26 May 2017 19:11 Go to previous messageGo to next message
Greg Lusk is currently offline Greg LuskFriend
Messages: 36
Registered: February 2017
Location: USA
Member
I see what you are saying now. We have to find the instance of IntrinsicFunction that exists in our global scope.
Re: Error When Serializing CrossReference [message #1764228 is a reply to message #1764225] Fri, 26 May 2017 20:30 Go to previous messageGo to next message
Greg Lusk is currently offline Greg LuskFriend
Messages: 36
Registered: February 2017
Location: USA
Member
Assuming that the global scope contains the instance of an IntrinsicFunction that I want to assign, how do I go about locating it in the global scope?
Re: Error When Serializing CrossReference [message #1764237 is a reply to message #1764228] Sat, 27 May 2017 05:29 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14669
Registered: July 2009
Senior Member
What about doing the same as you do in scope
ResourceSet resourceSet = resourceSetProvider.get();
URI uri = URI.createURI("classpath:/stdlib.stext");
Resource stdlib = resourceSet.getResource(uri, true);

Then query / Traverse the lib resource


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error When Serializing CrossReference [message #1764249 is a reply to message #1764237] Sat, 27 May 2017 10:57 Go to previous messageGo to next message
Greg Lusk is currently offline Greg LuskFriend
Messages: 36
Registered: February 2017
Location: USA
Member
That will definitely work for my unit test where I'm not initially parsing text.

I found another way to do it using a technique for obtaining the global scope that you described in another post. I wrote a second test that is closer than my original test to our real world scenario. I parse some text first and obtain a model. From that model, I can obtain the global scope from its root element:

@Inject StructuredTextScopeProvider scopeProvider
...
...
func = block.globalScope.intrinsicFunctions.filter[f|f.name == node.operatorType.toString].head


def IScope globalScope(FunctionBlock block) {
		scopeProvider.delegate.getScope(block.eContainer, StructuredTextPackage.Literals.CALL__FUNC)
	}


def List<IntrinsicFunction> intrinsicFunctions(IScope scope) {
	Lists.transform(
		scope.allElements.filter[o|o.EObjectOrProxy instanceof IntrinsicFunction].map[EObjectOrProxy].toList,
		eObjectToIntrinsicFunction
		)
	}


So the entire solution appears to be:
1. Include a custom ResourceDescriptionStrategy in the project
2. Include a GlobalScopeProvider in the project and make sure that an instance of it is injected
3. Include a custom ScopeProvider that calls the GlobalScopeProvider for non-local references.
3. Parse some valid text.
4. Obtain the global scope using the scope provider's delegate in order to get all the EObject instances for the EObjectDescriptions in the scope
Re: Error When Serializing CrossReference [message #1764250 is a reply to message #1764249] Sat, 27 May 2017 11:21 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14669
Registered: July 2009
Senior Member
You can ask the scope for elements with a certain Name btw

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Error When Serializing CrossReference [message #1764251 is a reply to message #1764250] Sat, 27 May 2017 11:53 Go to previous message
Greg Lusk is currently offline Greg LuskFriend
Messages: 36
Registered: February 2017
Location: USA
Member
Perfect, thank you! That works even better!
Previous Topic:resolution of uriFragment '|0' failed.
Next Topic:How to export Xtext project referencing to UML for support the Xtext Editor
Goto Forum:
  


Current Time: Fri Apr 26 19:47:37 GMT 2024

Powered by FUDForum. Page generated in 0.04763 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top