codeconsole commented on PR #3024:
URL: https://github.com/apache/groovy/pull/3024#issuecomment-6400630045

   Pushed 9d2a811ee9. Replies in the order of the review:
   
   1. Kept, documented and tested in 6190c30aaf. The asymmetry is the 
runtime's. With indy, the cast to `Boolean` returns `null` as is 
(`CastSelector.handleBoolean`) but calls `asBoolean` through the meta class on 
any other value, so inside a category that overrides `asBoolean(Boolean)`, 
`$INIT` passes `false` for `true`. A direct `true` would diverge there; a 
direct `null` cannot. A `boolean` parameter unboxes without `asBoolean`, so 
`true` and `false` go direct there. `Boolean.TRUE` is a property expression, 
not a literal, so it keeps `$INIT`. 
`testBooleanArgumentsFollowTheCastOfTheRuntime` checks the path for each 
combination, and `testBooleanArgumentsUnderACategoryThatOverridesAsBoolean` the 
values; allowing `true` for `Boolean` fails both, rejecting `null` fails the 
first.
   2. Fixed in 083bd6b24f, in both places: `completeEnum` had the same cast, so 
a guard in `canInitDirectly` alone would only have moved the 
`ClassCastException` (master throws it there too). A non-list initial value is 
now the only argument, as `EnumHelper.addEnumConstant` treats it, and then 
follows the usual rules. The `testOnlyArgumentOutsideAList*` tests use a parser 
plugin that leaves the argument unwrapped; they fail without the change.
   3. Changed in 001ced2e4d: a varargs constructor now disables direct init 
only where it can win. `calculateParameterDistance` adds at least `1 << 44` to 
a varargs call, which outweighs the distance of the matching-arity constructor, 
except when the varargs constructor has the call's arity and the last argument 
is `null` (no penalty: master picks `E(String, Object...)` over `E(String, 
Integer)` for `('two', null)`). That case, and constants that match only as 
varargs, keep `$INIT`, with a comment on the `return null`. A 912-enum varargs 
matrix (dynamic and `@CompileStatic`, indy and classic) matches master value 
for value. 
`testVarargsConstructorBesideMatchingConstructorCallsConstructorDirectly`, 
`testVarargsConstructorForAnyArgumentsBesideMatchingConstructorCallsConstructorDirectly`,
 `testNullLastArgumentForAVarargsConstructorOfTheSameArityUsesInitHelper`, 
`EnumTest.testLiteralArgumentsBesideAVarargsConstructor`.
   4. Fixed in e50ac46974: the class generator writes the call through 
`visit(GroovyCodeVisitor)`, which passes itself to `write(mv, generator)`, and 
no field holds it. `visit(MethodVisitor)` still writes a constant without 
arguments and throws a `GroovyBugError` instead of an NPE for one with 
arguments, since only the generator can load those (emitting the `$INIT` call 
needs it too). `testOnlyTheClassGeneratorWritesTheArgumentsOfAConstant`.
   5. Fixed in e50ac46974: any other visitor visits `initCall` again. Such 
visitors exist: the AST browser and `AstNodeToScriptAdapter` run after the 
class generator at the Class Generation phase. They showed 
`/*BytecodeExpression*/` at 48a40f5b6b and show `E.$INIT('ONE', 0, 'one')` 
again, as on master. 
`testOtherVisitorsSeeTheInitCallsThatTheDirectCallsReplace`.
   6. Added to the Javadoc of `substitute` in 0719570757: transforms that 
rewrite `$INIT` decide the path, and so whether the enum needs constructor 
reflection, in both directions 
(`testArgumentAddedByATransformToEveryConstantCallsConstructorDirectly`, 
`testInitCallReplacedByATransformKeepsTheEnumOnTheEmittedCalls`).
   7. Spelled out in the class Javadoc (0719570757) and the PR description: 
enums whose constants all have literal arguments, which always went through 
`$INIT` before, are now created out of a meta class's sight too. Their opt-out 
is one non-literal argument, such as `'one'.toString()` for `'one'` 
(`testNonLiteralArgumentKeepsConstantCreationOpenToMetaClassInterception`).
   8. `box()` returns at once for a reference type (OperandStack.java:233). 
`testClassLiteralArgumentsCallConstructorDirectly` (6997620fe3) pins `LDC 
String.class`, `LDC Integer.class` and `GETSTATIC Integer.TYPE`, each followed 
directly by `INVOKESPECIAL`.
   
   Test gaps:
   - `Boolean`/`null`: item 1 (6190c30aaf).
   - `ListExpression` guard: item 2 (083bd6b24f).
   - Class literal: item 8 (6997620fe3).
   - `Character`/`char`: added in 6997620fe3. Groovy has no char literal, so a 
transform adds a `Character` constant. It goes direct to `char` and 
`Character`, and keeps `$INIT` for `int`, where the runtime finds no 
constructor rather than widening (`testCharacterConstantArguments`, 
`EnumTest.testCharacterConstantArgumentsAddedByATransform`).
   - Static compiler's `$INIT` form: 
`testInitCallsInTheFormOfTheStaticCompilerCallConstructorDirectly` (6997620fe3) 
asserts the `MethodCallExpression` form just before class generation and the 
direct bytecode; 
`testTransformsSeeTheInitCallsOfConstantsThatAreCreatedDirectly` asserts the 
`StaticMethodCallExpression` form of a dynamic enum. Disabling either branch of 
`initArguments` fails them.
   
   Nits:
   - `transformExpression`: no change.
   - Named in 9d2a811ee9: 
`org.codehaus.groovy.classgen.EnumConstantInit.constantAssignments`, like the 
`ClosureWriter` keys.
   - `setSourcePosition(initCall)`: still in place.
   - By design; stated in the Javadoc of `substitute` (0719570757). With item 
5, visitors that run after the class generator see the `$INIT` calls too.
   
   Without the change, 26 tests fail: 24 of the 50 new tests and the 2 
rewritten ones. The matrices in the description were re-run on this head with 
indy and with classic call sites; the values and exceptions match master apart 
from closure identity hashes.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to