paulk-asert commented on PR #2998:
URL: https://github.com/apache/groovy/pull/2998#issuecomment-6464333806
Thanks Daniel. Changed to cover the items you asked for:
1. **Mutual recursion:** added `testMutuallyRecursiveCallsUseDeclaredType`.
It's two private `def` methods calling each other, with a String base case,
under `@CompileStatic`. It runs in both declaration orders, so either method
can be the one checked first. In both orders, the call back into the method
being checked gets the declared `Object`, so nothing is published for either
method, and `.toUpperCase()` still fails.
2. **Closure-shared return:** added
`testClosureSharedVariableUsesDeclaredType`. A method returns a local variable
after a closure has assigned it `1`, and the call keeps the declared type.
3. **Package-private / protected under SC:** yes, that's intentional. Both
can be overridden, so even under static compilation there's no sole
implementation. I've added a sentence to the `hasSoleImplementation` Javadoc
saying so.
4. **Named LUBs:** agreed, this is deliberately conservative for a first
cut. For example, a `Number` local that holds an `Integer` and later a
`BigDecimal` gets `Object` rather than `Number`. If it's ever relaxed, a
positive test with a shared supertype is where I'd start.
5. **Other classes in the same compilation unit:** agreed. It's a known
limitation and `testMethodOfAnotherClassUsesDeclaredType` documents it. Happy
to track it as follow-up work.
6. **Nits:**
- A `@CompileStatic` plain enum behaves the same as the `@TypeChecked`
case: `A.m().toUpperCase()` compiles and runs.
- You're right about my wording. A closure in an instance method keeps
the declared type, but a closure in a static method still sees the inferred
type, because `this` there is the class.
7. **GROOVY-12445:** it has landed and is already in the branch's base. The
conflict I expected in `addTypeCheckingInfoAnnotation` didn't happen. The
reader keeps its own decoder rather than using `inferredReturnOrDeclared`.
Beyond the version check, it also has to handle an unreadable payload, reject
unions, mixed-type bounds and type parameters, and check that every named class
is on the classpath.
I also made one clarification to COMPATIBILITY.md: the annotation is written
only on methods that are type checked (`@TypeChecked` or `@CompileStatic`). A
dynamically compiled method records nothing, so its callers keep its declared
return type.
On the binary-contract point: I checked a statically compiled caller built
against a library whose `static def name()` returned `'x'`, then recompiled
only the library to return `42`. The caller has a `checkcast String` after the
call, so it fails with `ClassCastException` at the use site rather than a
`VerifyError`.
--
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]