I can report progress. Turns out there were two problems.
The error message that I was getting concerning <assignment operator>: "="
not being supported had to do with how I built the token for the
BinaryExpression.
I was using:
new BinaryExpression(
sV, // a VariableExpression
new Token( Types.ASSIGNMENT_OPERATOR, '=', -1, -1),
rtV // another VariableExpression
When I examined the AST that was generated after the transform, I noticed
that
the corresponding token mentioned: <assignment operator>. But, if I looked
at
a separate AST from hand written code that matched the output of the
transform,
that token mentioned: symbol "=". Not the same
After a quick Google search I hit upon:
new BinaryExpression(
sV, // a VariableExpression
Token.newSymbol( '=', -1, -1),
rtV // another VariableExpression
This gets rid of the error! I'm not sure why the first way to build a Token
doesn't
work. I'll also note that there are a number code examples using the first
approach that turn up in a web search. In any case, I'm happy to have one
that
does work.
At this point, applying the VariableScopeVisitor that Paul suggested seems
to
clean up my remaining problem with scoping issues.
Yeah!
On to the next wall, how to generate a table of method signatures (at
transform time)
for all the methods defined in the user written classes (marked with my
annotation)...
Many thanks,
Ed
On 02/20/2017 12:06 PM, Ed Clark wrote:
Ok, poking around the source for VariableScopeVisitor didn't provide me
with any insights. It did lead me to try
VariableScopeVisitor scopeVisitor = new VariableScopeVisitor( source,
true)
but I still get the error:
BUG! exception in phase 'class generation' in source unit
'CtxTest2.groovy' Operation: (<assignment operator>: "=" ) not supported
One possible twist that I noticed, is if I run my test script under
groovyConsole
I get one error message. But, if I run the equivalent code (with a 'main')
as a
standalone groovy file, the error message is printed twice. Not sure what
that
indicates.
But, it is tied to my inserted statements. If I comment out the statement
insertions, the compiler is happy. So I'm guessing I'm building bad
statements.
What is the proper way to build a statement that set a property that is
defined in a base class (i.e., extended by a class that gets instantiated)?
I'm currently doing:
VariableExpression cV = new VariableExpression( '__currentContext')
// PropertyExpression cP = new PropertyExpression( cnStack[ -1],
'__currentContext')
ExpressionStatement currStmt = new ExpressionStatement(
new BinaryExpression(
cV, // also tried assigning to cP
instead of cV
new Token(Types.ASSIGNMENT_OPERATOR, "=", -1, -1),
cnStack[ -1]
// new MethodCallExpression(
VariableExpression.THIS_EXPRESSION,
// new
ConstantExpression( 'getDelegate'),
// new
ArgumentListExpress())
)
)
blockStatement.statements.add( 0, currStmt)
(I've tried with and without the VariableScopeVisitor call, and with and
without
a call to "blockStatement.variableScope.putReferencedClassVariable( cv)".)
So, does this look like the correct way to set the value of a property that
is
inherited from a base class?
(The somewhat frustrating thing is the resultant AST with the inserted
statements
looks correct after the transform (up through the Instruction Selection
phase).
In fact, if I type that code into a separate groovyConsole, it runs.)
Thanks for your time,
Ed
On 02/16/2017 04:41 PM, Paul King wrote:
Do you have something like:
VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source)
scopeVisitor.visitClass(cNode)
for each of your closure(s)? Where cNode is a closure's classNode?
Cheers, Paul.