appendArguments(..) generating comments instead of content [message #1742541] |
Sun, 04 September 2016 00:13 |
Edward Mallia Messages: 8 Registered: September 2016 |
Junior Member |
|
|
I have the following grammar (snippets of):
Action:
'action' name=ID '(' actionFormalParameters=FormalParameters ')' '=' action=ActionBlock;
ActionBlock returns xbase::XBlockExpression:
'{'
{ActionBlock}
(expressions+=ActionBlockStatement ';'?)*
'}';
ActionBlockStatement returns xbase::XExpression:
ActionRefInvocation | XExpressionOrVarDeclaration;
ActionRefInvocation:
actionRef=ActionRef '(' actionActualParameters=ActualParameters ')';
ActionRef hidden():
'#' actionRefId=[Action];
In other words, I want to be able to do something like this:
action a(String s) = {
println(s)
}
action b(String s) = {
#a(s)
}
In my compiler that extends XbaseCompiler, I have the following function to handle ActionRefInvocation:
override protected doInternalToJavaStatement(XExpression obj, ITreeAppendable appendable, boolean isReferenced) {
if (obj instanceof ActionRefInvocation) {
appendable.trace(obj)
appendable.newLine
val action = obj.actionRef.actionRefId
val actionParameters = obj.actionActualParameters
val actionClass = action.jvmElements.filter(JvmGenericType).filter[t|!t.isInterface].head
val objectName = "action" + uuidName
appendable.append('''«actionClass.fullyQualifiedName» «objectName» = new «actionClass.fullyQualifiedName»();''')
appendable.newLine
appendable.append('''«objectName».accept(''')
appendable.newLine
appendArguments(actionParameters.parameters, appendable)
appendable.append(");")
appendable.newLine
appendable.newLine
return
}
super.doInternalToJavaStatement(obj, appendable, isReferenced)
}
But the output I get from the compilation is the following, which of course does not compile because the function implementation of a expects a String argument.
public void accept(final int i) {
valour.documentation.actions.Action6 action07f90ee2b6004c4fb226bbe61c58c88f = new valour.documentation.actions.Action6();
action07f90ee2b6004c4fb226bbe61c58c88f.accept(
/* name is null */);
}
Also, I've noticed that if I change the example supplied above to:
action a(String s) = {
println(s)
}
action b() = {
#a("foo")
}
I get the following null pointer exception on the invocation of appendArguments(..)
!STACK 0
java.lang.NullPointerException
at org.eclipse.xtext.xbase.compiler.LiteralsCompiler.toJavaExpression(LiteralsCompiler.java:81)
at org.eclipse.xtext.xbase.compiler.LiteralsCompiler._toJavaExpression(LiteralsCompiler.java:73)
at org.eclipse.xtext.xbase.compiler.LiteralsCompiler.internalToConvertedExpression(LiteralsCompiler.java:41)
at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler.internalToConvertedExpression(FeatureCallCompiler.java:102)
at org.eclipse.xtext.xbase.compiler.XbaseCompiler.internalToConvertedExpression(XbaseCompiler.java:317)
at org.eclipse.xtext.xbase.compiler.TypeConvertingCompiler.internalToConvertedExpression(TypeConvertingCompiler.java:104)
at org.eclipse.xtext.xbase.compiler.TypeConvertingCompiler.internalToJavaExpression(TypeConvertingCompiler.java:47)
at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler.appendArgument(FeatureCallCompiler.java:1033)
at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler.appendArguments(FeatureCallCompiler.java:995)
at org.eclipse.xtext.xbase.compiler.FeatureCallCompiler.appendArguments(FeatureCallCompiler.java:989)
at mt.edu.um.cs.rv.ValourCompiler.doInternalToJavaStatement(ValourCompiler.java:70)
I'm not sure what I'm doing wrong here. I would appreciate your help.
Thanks
|
|
|
|
|
Re: appendArguments(..) generating comments instead of content [message #1743471 is a reply to message #1742702] |
Thu, 15 September 2016 17:59 |
Edward Mallia Messages: 8 Registered: September 2016 |
Junior Member |
|
|
Thanks for you reply Christian, and sorry for getting back late but was on vacation since.
In my inferrer, I am first creating an FunctionalInterface for the action
val consumableFunctionalInterface = action.toClass(
functionalInterfaceName,
[
annotations += annotationRef(FunctionalInterface)
interface = true
members += action.toMethod("accept", typeRef(void), [
static = false
^default = false
abstract = true
visibility = JvmVisibility.PUBLIC
action.actionFormalParameters.parameters.forEach [ p |
parameters += action.toParameter(p.name, p.parameterType)
]
])
]
)
and then creating an implementation of the FunctioanlInterface and plugging in the body of the action
val actionClass = action.toClass(
className,
[
superTypes += typeRef(functionalInterfaceName)
members += action.toMethod("accept", typeRef(void), [
static = false
visibility = JvmVisibility.PUBLIC
annotations += annotationRef(Override)
action.actionFormalParameters.parameters.forEach [ p |
parameters += action.toParameter(p.name, p.parameterType)
]
body = action.action
])
]
)
I have not implemented anything in terms of the type computer. Is this something that I should be extending ?
My definition of ActualParameter is the following:
ActualParameters:
{ActualParameters}(parameters+=XExpression (',' parameters+=XExpression)*)?;
Any guidance to help me get this set up in the proper way would be greatly appreciated.
|
|
|
Re: appendArguments(..) generating comments instead of content [message #1743474 is a reply to message #1743471] |
Thu, 15 September 2016 18:17 |
|
i was thinking of
Model:
actions+=Action+
;
Action:
'action' name=ID '(' (actionFormalParameters+=JvmFormalParameter (',' actionFormalParameters+=JvmFormalParameter)*) ')' '=' action=XBlockExpression;
def dispatch void infer(Model model, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
acceptor.accept(model.toClass("test.Demo")) [
for (a : model.actions) {
members += a.toMethod(a.name, Void.TYPE.typeRef) [
body = a.action
for (p : a.actionFormalParameters) {
parameters+=p
}
]
}
]
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
|
|
|
Re: appendArguments(..) generating comments instead of content [message #1743500 is a reply to message #1743491] |
Fri, 16 September 2016 05:13 |
|
you are missing to walk down into the actual params
public class MyDslTypeComputer extends XbaseTypeComputer {
@Override
public void computeTypes(XExpression expression, ITypeComputationState state) {
if (expression instanceof ActionRefInvocation) {
// TODO match formal and actual params in expectation (use expectation of formal param)
for (XExpression ap : ((ActionRefInvocation) expression).getActionActualParameters().getParameters()) {
state.withNonVoidExpectation().computeTypes(ap);
}
state.acceptActualType(getPrimitiveVoid(state));
return;
}
super.computeTypes(expression, state);
}
}
Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
|
|
|
|
Powered by
FUDForum. Page generated in 0.02479 seconds