This is an automated email from the ASF dual-hosted git repository.

emilles pushed a commit to branch GROOVY-10683
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY-10683 by this push:
     new ab38a1c987 GROOVY-11595: error for invalid modifiers on `for` or 
`catch` parameters
ab38a1c987 is described below

commit ab38a1c987f358272d164de1a54ccf95cd2a509a
Author: Eric Milles <[email protected]>
AuthorDate: Sun Mar 30 18:10:20 2025 -0500

    GROOVY-11595: error for invalid modifiers on `for` or `catch` parameters
---
 .../groovy/classgen/ClassCompletionVerifier.java   | 90 +++++++++++++++-------
 src/test/groovy/ForLoopTest.groovy                 |  2 +-
 2 files changed, 63 insertions(+), 29 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java 
b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
index 845c0dc5b3..5b0e0d48f4 100644
--- a/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/ClassCompletionVerifier.java
@@ -44,6 +44,7 @@ import org.codehaus.groovy.ast.expr.PropertyExpression;
 import org.codehaus.groovy.ast.expr.TupleExpression;
 import org.codehaus.groovy.ast.expr.VariableExpression;
 import org.codehaus.groovy.ast.stmt.CatchStatement;
+import org.codehaus.groovy.ast.stmt.ForStatement;
 import org.codehaus.groovy.ast.tools.GeneralUtils;
 import org.codehaus.groovy.ast.tools.ParameterUtils;
 import org.codehaus.groovy.control.SourceUnit;
@@ -58,10 +59,12 @@ import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
+import static java.lang.reflect.Modifier.isAbstract;
 import static java.lang.reflect.Modifier.isFinal;
 import static java.lang.reflect.Modifier.isNative;
 import static java.lang.reflect.Modifier.isPrivate;
 import static java.lang.reflect.Modifier.isProtected;
+import static java.lang.reflect.Modifier.isPublic;
 import static java.lang.reflect.Modifier.isStatic;
 import static java.lang.reflect.Modifier.isStrict;
 import static java.lang.reflect.Modifier.isSynchronized;
@@ -71,17 +74,10 @@ import static 
org.codehaus.groovy.ast.tools.GenericsUtils.addMethodGenerics;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.buildWildcardType;
 import static 
org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
 import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
-import static org.objectweb.asm.Opcodes.ACC_ABSTRACT;
 import static org.objectweb.asm.Opcodes.ACC_FINAL;
-import static org.objectweb.asm.Opcodes.ACC_NATIVE;
 import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
-import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
-import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
 import static org.objectweb.asm.Opcodes.ACC_STATIC;
-import static org.objectweb.asm.Opcodes.ACC_STRICT;
-import static org.objectweb.asm.Opcodes.ACC_SYNCHRONIZED;
 import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
-import static org.objectweb.asm.Opcodes.ACC_TRANSIENT;
 import static org.objectweb.asm.Opcodes.ACC_VOLATILE;
 
 /**
@@ -752,12 +748,46 @@ out:        for (ClassNode sc : superTypes) {
 
     @Override
     public void visitCatchStatement(final CatchStatement cs) {
+        List<String> modifiers = new ArrayList<>();
+        int mods = cs.getVariable().getModifiers();
+
+        if (isAbstract (mods)) modifiers.add("abstract" );
+        if (isPrivate  (mods)) modifiers.add("private"  );
+        if (isProtected(mods)) modifiers.add("protected");
+        if (isPublic   (mods)) modifiers.add("public"   );
+        if (isStatic   (mods)) modifiers.add("static"   );
+        if (isStrict   (mods)) modifiers.add("strictfp" );
+
+        for (String modifier : modifiers) {
+            addError("The catch " + getDescription(cs.getVariable()) + " has 
invalid modifier " + modifier + ".", cs);
+        }
+
         if 
(!(cs.getExceptionType().isDerivedFrom(ClassHelper.THROWABLE_TYPE))) {
             addError("Catch statement parameter type is not a subclass of 
Throwable.", cs);
         }
+
         super.visitCatchStatement(cs);
     }
 
+    @Override
+    public void visitForLoop(final ForStatement fs) {
+        List<String> modifiers = new ArrayList<>();
+        int mods = fs.getVariable().getModifiers();
+
+        if (isAbstract (mods)) modifiers.add("abstract" );
+        if (isPrivate  (mods)) modifiers.add("private"  );
+        if (isProtected(mods)) modifiers.add("protected");
+        if (isPublic   (mods)) modifiers.add("public"   );
+        if (isStatic   (mods)) modifiers.add("static"   );
+        if (isStrict   (mods)) modifiers.add("strictfp" );
+
+        for (String modifier : modifiers) {
+            addError("The variable '" + fs.getVariable().getName() + "' has 
invalid modifier " + modifier + ".", fs);
+        }
+
+        super.visitForLoop(fs);
+    }
+
     @Override
     public void visitMethodCallExpression(final MethodCallExpression mce) {
         super.visitMethodCallExpression(mce);
@@ -772,34 +802,38 @@ out:        for (ClassNode sc : superTypes) {
         }
     }
 
+    private void checkForInvalidDeclaration(final Expression exp) {
+        if (!(exp instanceof DeclarationExpression)) return;
+        addError("Invalid use of declaration inside method call.", exp);
+    }
+
     @Override
     public void visitDeclarationExpression(final DeclarationExpression 
expression) {
         super.visitDeclarationExpression(expression);
+
         if (expression.isMultipleAssignmentDeclaration()) return;
-        checkInvalidDeclarationModifier(expression, ACC_ABSTRACT, "abstract");
-        checkInvalidDeclarationModifier(expression, ACC_NATIVE, "native");
-        checkInvalidDeclarationModifier(expression, ACC_PRIVATE, "private");
-        checkInvalidDeclarationModifier(expression, ACC_PROTECTED, 
"protected");
-        checkInvalidDeclarationModifier(expression, ACC_PUBLIC, "public");
-        checkInvalidDeclarationModifier(expression, ACC_STATIC, "static");
-        checkInvalidDeclarationModifier(expression, ACC_STRICT, "strictfp");
-        checkInvalidDeclarationModifier(expression, ACC_SYNCHRONIZED, 
"synchronized");
-        checkInvalidDeclarationModifier(expression, ACC_TRANSIENT, 
"transient");
-        checkInvalidDeclarationModifier(expression, ACC_VOLATILE, "volatile");
-        if 
(ClassHelper.isPrimitiveVoid(expression.getVariableExpression().getOriginType()))
 {
-            addError("The variable '" + 
expression.getVariableExpression().getName() + "' has invalid type void", 
expression);
-        }
-    }
+        var vexp = expression.getVariableExpression();
+        List<String> modifiers = new ArrayList<>();
+        int mods = vexp.getModifiers();
+
+        if (isAbstract    (mods)) modifiers.add("abstract"     );
+        if (isNative      (mods)) modifiers.add("native"       );
+        if (isPrivate     (mods)) modifiers.add("private"      );
+        if (isProtected   (mods)) modifiers.add("protected"    );
+        if (isPublic      (mods)) modifiers.add("public"       );
+        if (isStatic      (mods)) modifiers.add("static"       );
+        if (isStrict      (mods)) modifiers.add("strictfp"     );
+        if (isSynchronized(mods)) modifiers.add("synchronized" );
+        if (isTransient   (mods)) modifiers.add("transient"    );
+        if (isVolatile    (mods)) modifiers.add("volatile"     );
 
-    private void checkInvalidDeclarationModifier(final DeclarationExpression 
expression, int modifier, String modName) {
-        if ((expression.getVariableExpression().getModifiers() & modifier) != 
0) {
-            addError("Modifier '" + modName + "' not allowed here.", 
expression);
+        for (String modifier : modifiers) {
+            addError("The variable '" + vexp.getName() + "' has invalid 
modifier " + modifier + ".", expression);
         }
-    }
 
-    private void checkForInvalidDeclaration(final Expression exp) {
-        if (!(exp instanceof DeclarationExpression)) return;
-        addError("Invalid use of declaration inside method call.", exp);
+        if (ClassHelper.isPrimitiveVoid(vexp.getOriginType())) {
+            addError("The variable '" + vexp.getName() + "' has invalid type 
void.", expression);
+        }
     }
 
     @Override
diff --git a/src/test/groovy/ForLoopTest.groovy 
b/src/test/groovy/ForLoopTest.groovy
index c4603382f9..5608a553fb 100644
--- a/src/test/groovy/ForLoopTest.groovy
+++ b/src/test/groovy/ForLoopTest.groovy
@@ -31,7 +31,7 @@ final class ForLoopTest {
 
     @ParameterizedTest
     @ValueSource(strings=[
-        
/*'public','private','protected','abstract','static',*/'native',/*'strictfp',*/'synchronized'
+        
'public','private','protected','abstract','static','native','strictfp','synchronized'
     ])
     void testFinalParameterInForLoopIsAllowed(String modifier) {
         // only 'final' should be allowed; other modifiers should be forbidden

Reply via email to