daniellansun commented on code in PR #2845:
URL: https://github.com/apache/groovy/pull/2845#discussion_r3889446708


##########
src/main/java/org/codehaus/groovy/control/GenericsVisitor.java:
##########
@@ -159,11 +189,61 @@ public void visitDeclarationExpression(final 
DeclarationExpression expression) {
      */
     @Override
     public void visitArrayExpression(final ArrayExpression expression) {
+        ClassNode elementType = expression.getElementType();
+        if (!isReifiable(elementType)) {
+            addError("generic array creation", expression);
+        }
         checkGenericsUsage(expression.getType());
 
         super.visitArrayExpression(expression);
     }
 
+    /**
+     * JLS 15.8.2: a class literal may not name a type variable.
+     */
+    @Override
+    public void visitClassExpression(final ClassExpression expression) {
+        ClassNode type = expression.getType();
+        if (type.isGenericsPlaceHolder()) {
+            addError("Cannot select from a type parameter " + 
type.getUnresolvedName(), expression);
+        }
+        super.visitClassExpression(expression);
+    }
+
+    /**
+     * Groovy represents the type operand of {@code instanceof} as a
+     * {@link ClassExpression}, but it is not a class literal. Skip it so
+     * {@link InstanceOfVerifier} can diagnose JLS 15.20.2.
+     */
+    @Override
+    public void visitBinaryExpression(final BinaryExpression expression) {
+        if (expression.getOperation().isA(Types.INSTANCEOF_OPERATOR)
+                && expression.getRightExpression() instanceof ClassExpression) 
{

Review Comment:
   Not forbidden by the grammar. `matchingType` / `standardType` still take type
   arguments so `instanceof List<?>` (and `instanceof Map<?,?>`) can parse
   (JLS 15.20.2 / 4.7 — unbounded wildcards are reifiable).
   
   `x instanceof Map<String,Integer>` is a parse error from
   `AstBuilder.rejectParameterizedInstanceof`
   (`Cannot perform instanceof check against parameterized type …`). The same
   applies to `!instanceof` and to bounded wildcards (`List<? extends T>`,
   `List<? super T>`).
   
   `GenericsVisitor` does not visit the `instanceof` operand as a class
   expression (that would treat it as `T.class`). It does run
   `checkGenericsUsage` on the type, so nested-type well-formedness matches
   javac / JDK `T6665356`:
   
   - `instanceof Outer<?>.Inner` is illegal when `Inner` is generic (raw member
     of a parameterized enclosing type);
   - `instanceof Outer.Inner<?>` is illegal (type arguments on a member of a
     raw type). The same form is rejected as a field type.
   
   `InstanceOfVerifier` still only checks primitives and type-parameter targets.
   We did **not** reject parameterized `instanceof` there: resolved `ClassNode`s
   often still carry declaration placeholders (`List<E>`), and treating those as
   a parameterized *use* breaks legitimate Groovy (reproduced on 
`groovy-macro`).
   
   The Java-vs-Groovy matrix is in `GenericsJavaCompatibilityTest` (JLS 4.7 /
   15.20.2). Reifiable cases include `list instanceof List<?>` with a
   `List<String>` left operand, `ArrayList<?>`, raw `List`, `Map<?,?>`,
   `Class<?>`, `List<?>[]`, `Outer<?>.Inner` (non-generic `Inner`),
   `Outer.Inner`, and `Outer<?>.Inner<?>`. Non-reifiable cases include
   `List<String>`, `Map<String,Integer>`, `!(o instanceof Map<String,Integer>)`,
   bounded and mixed wildcards, `List<String>[]`, `T` / `T[]`, `Class<C>` /
   `Class<? extends C>`, and `Outer<String>.Inner`.
   



-- 
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