Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Set XEpression local scope(How to create an derived scope containing external Resources for an XExpression)
Set XEpression local scope [message #1748650] Fri, 25 November 2016 17:09 Go to next message
Sven Uthe is currently offline Sven UtheFriend
Messages: 8
Registered: May 2016
Junior Member
Hi,

I want to include an XExpression into my DSL which works like the check( Expression ) in VIATRA:

Quote:

qualifiedName == eval(parentName + "." + simpleName);

The Java types of variables are inferred based on the EMF Ecore specification (using the generated Java classes).
Additional attribute constraints using the check() construct, similarly to eval():
check(aNumberVariable > aStringVariable.length());

Semantically equivalent to
true == eval(aNumberVariable > aStringVariable.length());

The Java types of variables are inferred based on the EMF Ecore specification (using the generated Java classes).

(From 5. under https://wiki.eclipse.org/VIATRA/Query/UserDocumentation/QueryLanguage#Advanced_Pattern_Constraints)


A shortened extract of my xtext grammar:

grammar eu.netide.deployment.topologyvalidation.Topo with org.eclipse.xtext.xbase.Xbase

import "http://www.eclipse.org/xtext/xbase/Xbase"

generate Topo "http://[..]/Topo"
Root:
	(submodules+=Module)*
;
SwitchModule returns Module:
	{SwitchModule}
	name=ValidID ':'
	Switch
	('{'
		constrain=XExpression
	'}')?
;


Additionally, there is an external Plugin-Project containing an ECore Model which includes among others a Switch Class.
This Class should be the Scope of the constrain. (like described in the VIATRA doc)
So in the end the user can use the Auto Completion to see all the members and operations the Switch Class provides.
Also, the TypeSystem should validate that the written code returns a boolean value at runtime.
Therefore I added a TypeCompute Class to my DSL:

class TopoTypeComputer extends XbaseWithAnnotationsTypeComputer {

	override computeTypes(XExpression expression, ITypeComputationState state) {
[...]
		if (expression instanceof SwitchModule) {
			val conditionExpectation = state.withExpectation(getRawTypeForName(typeof(Boolean), state));
			val predicate = expression.constrain;
			conditionExpectation.computeTypes(predicate);
[...]
		}
	}
}


To set the scope of the XExpression of the constrain I tried different approaches an none of them worked Sad
Here is the last one:

import Topology.Switch // The Class of the external ECore Model
[...]
class TopoScopeProvider extends AbstractTopoScopeProvider {
	
	@Inject extension JvmTypeReferenceBuilder

	override getScope(EObject context, EReference reference) {
		switch (context) {
[...]
			SwitchModule case reference == TopoPackage.Literals.SWITCH_MODULE__CONSTRAIN: {
				val declaredOperations = (typeRef(Switch).type as JvmDeclaredType).getDeclaredOperations();
				return Scopes.scopeFor(declaredOperations, [JvmOperation op |
						return QualifiedName.create(op.getSimpleName());
					], IScope.NULLSCOPE);
			}
			default: {
				return super.getScope(context, reference)
			}
		}
	}
}


Side notes:
I use the the ModelInferrer to generate Java Classes.
Beside searching this forum and googling around (didn't find the right search term), I looked at the VIATRA implementation (http://git.eclipse.org/c/viatra/org.eclipse.viatra.git/tree/query/plugins/org.eclipse.viatra.query.patternlanguage/src/org/eclipse/viatra/query/patternlanguage/typing). But this is tooooo freaky Very Happy
My Guess is, that I missed something like an URI/resource import of the ECore model to make it visible to the xtext grammar.
Re: Set XEpression local scope [message #1748651 is a reply to message #1748650] Fri, 25 November 2016 17:13 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
hi,

usually you do such things in the jvm model inferrer.

if you e.g. infer a method for each SwitchModule and add a parameter of type Switch and name it, then what you try to do will work out of the box.


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Set XEpression local scope [message #1748652 is a reply to message #1748651] Fri, 25 November 2016 17:26 Go to previous messageGo to next message
Sven Uthe is currently offline Sven UtheFriend
Messages: 8
Registered: May 2016
Junior Member
Thank you. That is clear.
But, I do not want a method with a parameter in my inferred Class.

In fact I want to hold a String in my inferred class containing the XExpression.
The inferred class will later on be used to generate VIATRA rules Wink
Then the XBase Expression can easily be pasted into a generated check expression.

Extract of my ModelInferrer:
if (submodule instanceof SwitchModule) {
	append(NodeModelUtils.findActualNodeFor(submodule.constrain).text)


So I need to somehow emulate the behaviour of VIATRA.
Re: Set XEpression local scope [message #1748654 is a reply to message #1748652] Fri, 25 November 2016 17:35 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hmm so your logic and your generation has nothing todo with each other ?
If so why not adapting the generator


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Set XEpression local scope [message #1748655 is a reply to message #1748654] Fri, 25 November 2016 17:38 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
hmmm i had a look at xbase code and the code you pasted and your code seems to be strange regarding the types

inside the type computer you may try a

state.assignType(IFeatureNames.IT, knownType, expectedType);

e.g.

public class DomainmodelXbaseTypeComputer extends XbaseTypeComputer {

@Override
public void computeTypes(XExpression expression, ITypeComputationState state) {
if (expression.eContainer() instanceof Operation) {
state.assignType(IFeatureNames.IT, state.getReferenceOwner().newReferenceTo(Switch.class).getType(), state.getReferenceOwner().newReferenceTo(Switch.class));
}
super.computeTypes(expression, state);
}

}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Fri, 25 November 2016 18:35]

Report message to a moderator

Re: Set XEpression local scope [message #1748659 is a reply to message #1748654] Fri, 25 November 2016 19:22 Go to previous messageGo to next message
Sven Uthe is currently offline Sven UtheFriend
Messages: 8
Registered: May 2016
Junior Member
Christian Dietrich wrote on Fri, 25 November 2016 18:35
Hmm so your logic and your generation has nothing todo with each other ?
If so why not adapting the generator

What do you mean by " adapting the generator"?
I am using the inferrer because I think it simplifies the class generation.
I could use the generator, but does this help me on this scoping problem?

Or did you mean the VIATRA generator?
I was thinking about extending the VIATRA generator, but I thought this would be a lot more time consuming?

So I read into the FeatureScopes.java from the xtext repo (didn't understand much).
I tried the code update (i use xtend so I reworked it a but):
It did not changed much I autocomplete doesn't show me anything and the debugger does not step into the if clause?

I'll try more tomorrow Thanks!
Re: Set XEpression local scope [message #1748660 is a reply to message #1748659] Fri, 25 November 2016 19:28 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Have a look at my updated post as well

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Set XEpression local scope [message #1748681 is a reply to message #1748660] Sat, 26 November 2016 17:27 Go to previous messageGo to next message
Sven Uthe is currently offline Sven UtheFriend
Messages: 8
Registered: May 2016
Junior Member
Thank you for your qualified and fast help.
Today, I poked around the computeTypes method: No success.
Overriding FeatureScopes is not an option because I am bounded to some deadlines.
At the end of this day I decided to take your first advice and it worked - as expected- like a charm.
So I hazard the consequences to have unnecessary functions in my generated code.

Cheers

[Updated on: Sun, 27 November 2016 11:54]

Report message to a moderator

Re: Set XEpression local scope [message #1748682 is a reply to message #1748681] Sat, 26 November 2016 18:18 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Hmm have To try this

I thought you don't use xbase compiler but text only
Can you please elaborate


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Set XEpression local scope [message #1748683 is a reply to message #1748682] Sat, 26 November 2016 18:29 Go to previous messageGo to next message
Sven Uthe is currently offline Sven UtheFriend
Messages: 8
Registered: May 2016
Junior Member
I have other construct in my language where I extended xbase XExpression and they will be compiled to java methods.
Therefore I wrote a class TopoXbaseCompiler extends XbaseCompiler.
My computeTypes(XExpression expression, ITypeComputationState state) also considers this extension. (There is another if else case in it)
But this should not affect this problem here?

state.assignType(IFeatureNames.IT,...)
was never been called:

override computeTypes(XExpression expression, ITypeComputationState state) {
		if (expression.eContainer() instanceof SwitchModule) {
			state.assignType(IFeatureNames.IT,
				state.getReferenceOwner().newReferenceTo(Switch).getType(),
				state.getReferenceOwner().newReferenceTo(Switch)
			)
		} else {
			super.computeTypes(expression, state);
		}
	}

[Updated on: Sat, 26 November 2016 18:50]

Report message to a moderator

Re: Set XEpression local scope [message #1748684 is a reply to message #1748683] Sat, 26 November 2016 19:00 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
i have not any compile problems with ints in my example.
you should hook into the type computation at the correct place somwhere arround org.eclipse.xtext.xbase.typesystem.internal.LogicalContainerAwareReentrantTypeResolver.computeTypes(ResolvedTypes, IFeatureScopeSession)

usually this is done automatically if you assign the expression to a body or a initializer but you dont


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Set XEpression local scope [message #1748705 is a reply to message #1748684] Sun, 27 November 2016 11:52 Go to previous messageGo to next message
Sven Uthe is currently offline Sven UtheFriend
Messages: 8
Registered: May 2016
Junior Member
The compilation problems were caused by mistake sorry for that.
Where do I get further information about hooking into the xbase typeComputer?
The most useful page I found was this slideshare:
http://www.slideshare.net/szarnekow/extending-the-xbase-typesystem
It doesn't help me much.
Is there a documentation other than the javadoc?

Is there a way to call the compilation manually from the inferrer?
XbaseCompiler.compile()???
Re: Set XEpression local scope [message #1748707 is a reply to message #1748705] Sun, 27 November 2016 12:06 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
No these are 3 different things

Inferrer
Type computer
jvmmodelgenerator / xbasecompiler

Lorenzo Beetins Xtext Book in the 2nd version contains some hints on that but I don't know if this covers your usecase since you are doing something xbase is not made for since you circumvent the inferrer


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Set XEpression local scope [message #1748712 is a reply to message #1748707] Sun, 27 November 2016 13:56 Go to previous message
Sven Uthe is currently offline Sven UtheFriend
Messages: 8
Registered: May 2016
Junior Member
I thought it could be another "ugly" hack to invoke the xbase compilation of the XExpression from the model inferrer (without rendering it into the inferred class) and as a side effect this triggers the TypeComputer call.
Previous Topic:Xcore on ANT or MWE workflow
Next Topic:EMFModelInferrer
Goto Forum:
  


Current Time: Fri Mar 29 10:11:50 GMT 2024

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

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

Back to the top