You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@groovy.apache.org by Saravanan Palanichamy <ch...@gmail.com> on 2023/04/03 00:04:51 UTC

Duplicate visits to expressions defined in RHS of a setter

Hello Groovy Devs

   - I have a class defined MyTestClass in java/kotlin (does not matter)
   - I have a groovy class defined MyClassDefinedInGroovy
   - I have code in a groovy function that is creating these classes and
   setting a variable in the object. I compile this with static compilation
   turned on
   - I visit this class using a simple visitor that prints all constants
   visited (I have attached both code and groovy file in this email)

For the class defined in java

   - In 3.0.16, all constants are visited twice. This is not what I would
   expect but at least it is consistent
   - In 3.0.5, the setters with a property based LHS are visited twice, but
   those with a variable based LHS, only one visit as expected

For the class defined in Groovy, In both 3.0.5 and 3.0.16, all constants
are visited only once. This is what I would expect

Multiple visits to the same code is causing an issue for me because I
collect metadata about the code for use elsewhere and I end up getting
duplicates that cannot be cleanly ignored (because its not just variables,
its anything on the RHS, closures, method calls, etc)

I debugged this a bit and found out that for classes imported from Java,
the compiler seems to be using PoppingMethodCallExpression and
PoppingListOfExpressionsExpression. The latter has code that initializes
the parent with two expressions, the tmp variable and the method call. The
method call also includes the tmp variable which I think is causing this
duplicate visit.

>
> public PoppingListOfExpressionsExpression(final TemporaryVariableExpression tmp, final PoppingMethodCallExpression call) {
>
>     // This array initialization with tmp and call is a problem because call also holds tmp and visits it
>
>     super(Arrays.asList(tmp, call));
>     this.tmp = tmp;
>     this.call = call;
> }
>
>
What are my options if I dont want to handle the duplicate visit? This
problem exists in some scenarios in 3.0.5 and is consistently a problem in
3.0.16

regards
Saravanan