Home » Modeling » TMF (Xtext) » xbaseCompiler methods
| |
Re: xbaseCompiler methods [message #1736508 is a reply to message #1736379] |
Thu, 30 June 2016 02:13 |
Mansour Al Messages: 44 Registered: June 2016 |
Member |
|
|
Now, here comes the confusing part. We go back again to "Expression-Vs-Statement". Reading on the Xtend pages https://www.eclipse.org/xtend/documentation/203_xtend_expressions.html :
Quote:
In Xtend everything is an expression and has a return type. Statements do not exist. That allows you to compose your code in interesting ways.
For example, you can have a try catch expression on the right hand side of an ...
So, here comes the question of what is an expression and what is a statement in Xtext ?
Assuming, that an expression has no side effect and always is a value, why XMemberCall in Xbase is considered an expression, when a member call may have side effect ?
Then we go to the DSL tutorial for a template language : https://eclipse.org/Xtext/documentation/207_template.html , and we see:
Quote:
The compiler now knows how to handle the new expressions in a statement context. In addition, we have to teach it to compile them in an expression context.
This is what the second method does: ....
Which makes me conclude, that a statement in Xtext may contain an expression, but an expression can not be a statement ... Am I wrong here ?
Assuming, this is correct (which I don't think), a XblockExpression is an "XExpression", however, it may contain multiple statements !
This is a bit confusing, especially when combined with writting the grammar. For example in Xtext, we write the grammar in a way not only to define the parsing, but we keep in the mind the processing
in the inferrer, compiler, ... etc.
So, assuming I have some parsing rule that I need to infer to:
SomeAction Optional_InstanceOfObjectInAnotherClass "MyValue1" "MyValue2" ;
AnotherAction 123 987 ;
Would this be an expression or a statement ? It has no assignment.
Anyone can help me by clarifying these concepts in "Xbase", or a link to a tutorial/documentation page would be highly appreciated, as I was not able to find one that explains this topic.
Thank you a lot in advance.
|
|
| | | | | | |
Re: xbaseCompiler methods [message #1737127 is a reply to message #1736996] |
Wed, 06 July 2016 00:35 |
Mansour Al Messages: 44 Registered: June 2016 |
Member |
|
|
Sorry Christian, I didn't clarify my question. After I reread it, it's a bit confusing. Let's try again !
I have an expression. The expression is processing in the inferrer. Once the Compiler is called to process EObjects under this expression, the inferrer role is over, and it's the compiler role to produce the valid java code (assuming we are producing java).
Now inside the compiler, we have many methods to process an expression. These methods, mainly produce a valid java code from predefined expressions in xbase. When we are processing of creating a new expression, this XExpression may contain other EObjects.
My question is, how do we process them ? With what method ? So, let's say I have this grammar:
Action returns xbase::XExpression:
{Action} type=JvmTypeReference args=Arguments ";";
Arguments:
{Arguments} targets+=(UIElement)* (":" data+=Datum+)?;
UIElement :
{UIElement} value=XExpression;
Datum returns xbase::XExpression:
{Datum} value=(XLiteral | PropRef);
PropRef:
ns=NS ":" prop=QualifiedName;
Note that UIElement is not an expression, but it's a delegate ParserRule and a wrapper for an expression.
Note that PropRef is NOT an expression, but XLiteral is an expression, and both create an instance of Datum Expression ! (Is this the right way) ?
Now, we have in the compiler:
override protected doInternalToJavaStatement(XExpression expr, ITreeAppendable tree, boolean isReferenced) {
switch expr {
.....
Action: {
..........
for (target : action.args.targets) {
target.value.internalToConvertedExpression(tree);
}
for (datum : action.args.data) {
datum.internalToConvertedExpression(tree);
}
......
}
default: {
super.doInternalToJavaStatement(expr, tree
....
And,
override protected internalToConvertedExpression(XExpression expr, ITreeAppendable tree) {
switch expr {
UIElement: {
internalToConvertedExpression(expr.value, tree)
}
Datum: {
internalToConvertedExpression(expr.value, tree) // This will not work because expr.value does not always yield an expression. It can be XLiteral or PropRef !
}
PropRef: {.....}
default: {
super.internalToConvertedExpression(expr, tree)
}
....
Based on this, how can I process the "Argument" Expression ? What I am after here, is a method like:
compile(Datum d){
if (d.value instance of PropRef) ...
else if (d instance of XLiteral) ....
}
None, of the exiting methods takes a non-Expression. Is there one that we can override ?
Am I using doInternalToJavaStatement and internalToConvertedExpression in the correct place ??
None of the methods can take an instance of EObject !
Thank you.
|
|
| |
Re: xbaseCompiler methods [message #1737293 is a reply to message #1737133] |
Thu, 07 July 2016 03:28 |
Mansour Al Messages: 44 Registered: June 2016 |
Member |
|
|
Christian, this is the grammar: https://github.com/malakeel/myDsl/blob/master/org.xtext.example.mydsl/src/org/xtext/example/mydsl/MyDsl.xtext
and the compiler: https://github.com/malakeel/myDsl/blob/master/org.xtext.example.mydsl/src/org/xtext/example/mydsl/jvmmodel/MyDslCompiler.xtend
As you can see the compiler is really messy but working. A small model test file:
suite MyTest using (testFile.xml ){
Click MyOtherPage.text ;
prepare {
Fill MyPage2.element : "How to use this text" ;
Fill MyPage.text : and:my.impl "How to use this 123" ;
Click MyOtherPage.element ;
Fill MyPage.text MyPage.text : and:my.impl "How to use this 123" ;
Fill ;
Fill MyPage.text : and:my.impl "How to use this 123 " ;
Fill MyPage.getValues(9) : "wow";
test anotherTest using (some.xml){
Fill MyPage.text ;
Fill MyPage.text : "How to use this 123" ;
}
test myTestCaseSample using (some.xml ) {
Fill MyPage2.element ;
}
}
}
produces the desired following results. However, since I need to do add more eclipse support, like inferring and auto suggest constructor arguments with their types, I need the grammar and compiler to be as clean as possible. I am hoping to eliminate the use of expression where it's not needed, and reduce ParserRules or increase them for clarity.
@SuppressWarnings("all")
public class MyTest {
private MyContextManager ctx;
@BeforeClass
public static void beforeSuite() {
(new actions.Click(MyOtherPage.text)).exec();
}
@Before
public void beforeTest() {
(new actions.Fill(MyPage2.element,"How to use this text")).exec();
(new actions.Fill(MyPage.text,ctx.get("and:my.impl"),"How to use this 123")).exec();
(new actions.Click(MyOtherPage.element)).exec();
(new actions.Fill(MyPage.text,MyPage.text,ctx.get("and:my.impl"),"How to use this 123")).exec();
(new actions.Fill()).exec();
(new actions.Fill(MyPage.text,ctx.get("and:my.impl"),"How to use this 123 ")).exec();
(new actions.Fill(MyPage.getValues(9),"wow")).exec();
}
@Test
public void anotherTest() {
(new actions.Fill(MyPage.text)).exec();
(new actions.Fill(MyPage.text,"How to use this 123")).exec();
}
@Test
public void myTestCaseSample() {
(new actions.Fill(MyPage2.element)).exec();
}
@After
public void afterTest() {
}
}
If I can your recommendations it will be great. The reason I asked about using existing method for compiling non-expressions is to ensure I am not adding anything that does not need to be there. I am having hard utilizing unassigned actions in my grammars, and I don't know if they will help reducing the complexity a bit.
Thank you.
|
|
| |
Re: xbaseCompiler methods [message #1737299 is a reply to message #1737294] |
Thu, 07 July 2016 06:11 |
|
i would have thought of
class MyDslTypeComputer extends XbaseTypeComputer {
override computeTypes(XExpression expression, ITypeComputationState state) {
if (expression instanceof Action) {
_computeTypes(expression as Action, state);
} else if (expression instanceof PropRef) {
state.acceptActualType(state.getReferenceOwner().newReferenceTo(Object))
} else {
super.computeTypes(expression, state)
}
}
protected def void _computeTypes(Action action, ITypeComputationState state) {
for (t : action.args.targets) {
println("TODO better logic here ?!?")
val iaction = state.getReferenceOwner().getServices().getTypeReferences().findDeclaredType(
"org.example.ILocator", state.referenceOwner.contextResourceSet)
state.withExpectation(
state.referenceOwner.newParameterizedTypeReference(iaction)
).computeTypes(t)
}
for (t : action.args.data) {
state.withNonVoidExpectation.computeTypes(t)
}
state.acceptActualType(getTypeForName(Void.TYPE, state), ConformanceFlags.CHECKED_SUCCESS)
}
}
class MyDslCompiler extends XbaseCompiler {
override protected doInternalToJavaStatement(XExpression expr, ITreeAppendable tree, boolean isReferenced) {
switch expr {
InitBody: {
tree.newLine
for (action : expr.expressions)
action.doInternalToJavaStatement(tree, isReferenced);
}
TestBody: {
tree.newLine
for (action : expr.expressions)
action.doInternalToJavaStatement(tree, false);
}
PropRef: {
if (isReferenced) {
val propRef = expr
tree.newLine().append("final ");
serialize(getType(propRef), propRef, tree);
tree.append(" ");
val variableName = tree.declareSyntheticVariable(propRef, "_propRef");
tree.append(variableName).append(" = ");
propRef.compile(tree)
tree.append(";");
} else {
throw new IllegalStateException
}
}
Action: {
val action = expr as Action;
for (t : action.args.targets) {
internalToJavaStatement(t, tree, true);
}
for (d : action.args.data) {
tree.newLine
val name = tree.declareVariable(d, "data")
serialize(getType(d), d, tree);
tree.append(" ")
tree.append(name);
tree.append(" = ")
internalToConvertedExpression(d, tree)
tree.append(";").newLine
}
tree.newLine
tree.trace(action)
tree.append("(new ");
tree.append(action.type.qualifiedName + "(");
var itr = action.args.targets.iterator
while (itr.hasNext) {
tree.append(itr.next.getVarName(tree))
if (itr.hasNext)
tree.append(",")
}
if (action.args.targets.size > 0 && action.args.data.size > 0) {
tree.append(",")
}
val dataItr = action.args.data.iterator
while (dataItr.hasNext) {
tree.append(dataItr.next.getVarName(tree))
if (dataItr.hasNext)
tree.append(",")
}
tree.append(")).exec();").newLine
}
default: {
super.doInternalToJavaStatement(expr, tree, isReferenced)
}
}
}
override protected internalToConvertedExpression(XExpression expr, ITreeAppendable tree) {
switch expr {
PropRef: {
expr.compile(tree)
}
default: {
super.internalToConvertedExpression(expr, tree)
}
}
}
def void compile(PropRef ref, ITreeAppendable tree) {
tree.append("ctx.get(\"");
tree.append(ref.ns);
tree.append(":" + ref.prop + "\")");
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Day Job: https://www.everest-systems.com
|
|
|
Goto Forum:
Current Time: Mon Oct 07 05:25:01 GMT 2024
Powered by FUDForum. Page generated in 7.31750 seconds
|