codeconsole commented on PR #3286:
URL: https://github.com/apache/groovy/pull/3286#issuecomment-6773195812
@daniellansun thanks. I reproduced each case against the branch and against
javac. New commits on top of 2ce6046aa3, after merging master:
1. **Enclosing type arguments.** `erasureOf` drops the enclosing type too,
so an `Outer<String>.Inner` receiver gives `Class<? extends Outer.Inner>`. I
did it there and not in `ClassNode.getPlainNodeReference`, which is documented
to copy the enclosing type and has many other callers. `Class<? extends
Outer.Inner>` is accepted and `Class<? extends Outer<String>.Inner>` is
rejected.
One difference from javac is left: inside `Outer<T>.Inner`, the simple
name in `Class<? extends Inner>` is still accepted. The resolver gives a simple
name no enclosing parameterization, so `Inner` and `Outer.Inner` are the same
type to the checker. Also, the error message prints the raw inner type as
`Outer<T>.Inner`. That is how `GenericsType` prints a non-static inner type
that has no enclosing type, on master as well.
2. **Raw bound against a parameterized bound.**
`StaticTypeCheckingSupport.upperBoundEscapes` is new, next to
`concreteArgumentContainsWildcard` and `typeVariableBoundEscapes`, and is
called from the same two places: `checkTypeGenerics` (assignment and return)
and the declared-parameter check in `typeCheckMethodsWithGenerics`. `? extends
A` is rejected for `? extends B` when `B` is parameterized, or has a
parameterized enclosing type, and `A` is raw; and when `B` is a type variable
and `A` is not one.
Your three returns are now errors, and so are the two hand-written cases
(`Class<? extends List>` as `Class<? extends List<String>>`, and `Class<?
extends Number>` as `Class<? extends T>`). The argument position is covered
too, since javac rejects it as well: `accept(strings.getClass())` for
`accept(Class<? extends List<String>>)`.
Left as before: a raw type that is not a wildcard bound (`List<String> x
= rawList`, or `Class<ArrayList>` for `Class<? extends List<String>>`), a
source bound that is a type variable, an inference variable, and a property of
a raw receiver (`rawHolder.type = c` for a `Class<? extends T> type`).
One consequence to be aware of: `<T> Class<? extends T> typeOf(T t) {
t.getClass() }` compiled before this PR, with `getClass()` as `Class<?>`, and
is now an error, as in javac, which wants the cast.
3. **Intersection.** `erasureOf` takes the leftmost component, so `((Number
& Runnable) o).getClass()` is `Class<? extends Number>` and is rejected for
`Class<? extends Runnable>`.
4. **Spread.** `PropertyLookup.visitMethod` gives `Object#getClass` the same
type, so `list*.class` is `List<Class<? extends String>>`, like
`list*.getClass()`.
5. **Tests.** `GenericsSTCTest` records the inferred type with `@ASTTest`
for the nested, intersection and spread receivers, and has the negative cases
for the three returns, the assignment, the argument, and the two hand-written
bounds, with the forms that must keep compiling beside them.
`GenericsJavaCompatibilityTest` gets six negative cases checked against javac
(parameterized receiver, `T extends Comparable<T>`, `this` in a generic class,
`Outer<String>.Inner`, the intersection, and `Class<? extends Number>` for
`Class<? extends T>`) and the positive `Outer.Inner` one. The eleven new
negative and inferred-type tests fail without the change.
6. **CI.** Master is merged, so
`StaticCompileRuntimePackageTest.testSystemProperty` has the restored property.
Class literals are untouched: only a zero-argument `getClass` declared on
`Object` takes the new path. GROOVY-12754 (#3285) is still the first commit
here and has to go in first.
--
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]