Skip to main content



      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 12:09 Go to next message
Eclipse UserFriend
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 12:13 Go to previous messageGo to next message
Eclipse UserFriend
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.
Re: Set XEpression local scope [message #1748652 is a reply to message #1748651] Fri, 25 November 2016 12:26 Go to previous messageGo to next message
Eclipse UserFriend
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 12:35 Go to previous messageGo to next message
Eclipse UserFriend
Hmm so your logic and your generation has nothing todo with each other ?
If so why not adapting the generator
Re: Set XEpression local scope [message #1748655 is a reply to message #1748654] Fri, 25 November 2016 12:38 Go to previous messageGo to next message
Eclipse UserFriend
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);
}

}

[Updated on: Fri, 25 November 2016 13:35] by Moderator

Re: Set XEpression local scope [message #1748659 is a reply to message #1748654] Fri, 25 November 2016 14:22 Go to previous messageGo to next message
Eclipse UserFriend
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 14:28 Go to previous messageGo to next message
Eclipse UserFriend
Have a look at my updated post as well
Re: Set XEpression local scope [message #1748681 is a reply to message #1748660] Sat, 26 November 2016 12:27 Go to previous messageGo to next message
Eclipse UserFriend
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 06:54] by Moderator

Re: Set XEpression local scope [message #1748682 is a reply to message #1748681] Sat, 26 November 2016 13:18 Go to previous messageGo to next message
Eclipse UserFriend
Hmm have To try this

I thought you don't use xbase compiler but text only
Can you please elaborate
Re: Set XEpression local scope [message #1748683 is a reply to message #1748682] Sat, 26 November 2016 13:29 Go to previous messageGo to next message
Eclipse UserFriend
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 13:50] by Moderator

Re: Set XEpression local scope [message #1748684 is a reply to message #1748683] Sat, 26 November 2016 14:00 Go to previous messageGo to next message
Eclipse UserFriend
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
Re: Set XEpression local scope [message #1748705 is a reply to message #1748684] Sun, 27 November 2016 06:52 Go to previous messageGo to next message
Eclipse UserFriend
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 07:06 Go to previous messageGo to next message
Eclipse UserFriend
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
Re: Set XEpression local scope [message #1748712 is a reply to message #1748707] Sun, 27 November 2016 08:56 Go to previous message
Eclipse UserFriend
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: Tue May 13 21:43:39 EDT 2025

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

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

Back to the top