Set XEpression local scope [message #1748650] |
Fri, 25 November 2016 17:09  |
Sven Uthe 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 
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 
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 #1748655 is a reply to message #1748654] |
Fri, 25 November 2016 17:38   |
|
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);
}
}
Need professional support for Xtext, Xpand, EMF?
Go to: https://www.itemis.com/en/it-services/methods-and-tools/xtext
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 #1748681 is a reply to message #1748660] |
Sat, 26 November 2016 17:27   |
Sven Uthe 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 #1748683 is a reply to message #1748682] |
Sat, 26 November 2016 18:29   |
Sven Uthe 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
|
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.01965 seconds