Set XEpression local scope [message #1748650] |
Fri, 25 November 2016 12:09  |
Eclipse User |
|
|
|
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 #1748712 is a reply to message #1748707] |
Sun, 27 November 2016 08:56  |
Eclipse User |
|
|
|
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.
|
|
|
Powered by
FUDForum. Page generated in 0.07090 seconds