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 = newVariableExpression( '__currentContext')
//    PropertyExpression cP = newPropertyExpression( cnStack[ -1], 
'__currentContext')
    ExpressionStatement currStmt = newExpressionStatement(
        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.


Reply via email to