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

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


The following commit(s) were added to refs/heads/master by this push:
     new 6e6f304643 GROOVY-11457: STC: `try`/`catch`/`finally` conditional 
assignments
6e6f304643 is described below

commit 6e6f304643a68881dec973e62baf5add7f8cad50
Author: Eric Milles <eric.mil...@thomsonreuters.com>
AuthorDate: Wed Sep 4 14:16:10 2024 -0500

    GROOVY-11457: STC: `try`/`catch`/`finally` conditional assignments
---
 .../transform/stc/StaticTypeCheckingVisitor.java   | 25 ++++++++++-------
 .../groovy/transform/stc/STCAssignmentTest.groovy  | 31 +++++++++++++++++++++-
 2 files changed, 46 insertions(+), 10 deletions(-)

diff --git 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
index 7abf95d5cf..7c0dae50f2 100644
--- 
a/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
+++ 
b/src/main/java/org/codehaus/groovy/transform/stc/StaticTypeCheckingVisitor.java
@@ -4532,18 +4532,25 @@ trying: for (ClassNode[] signature : signatures) {
 
     @Override
     public void visitTryCatchFinally(final TryCatchStatement statement) {
-        List<CatchStatement> catchStatements = statement.getCatchStatements();
-        for (CatchStatement catchStatement : catchStatements) {
-            ClassNode exceptionType = catchStatement.getExceptionType();
-            
typeCheckingContext.controlStructureVariables.put(catchStatement.getVariable(), 
exceptionType);
-        }
+        Map<Parameter, ClassNode> vars = 
typeCheckingContext.controlStructureVariables;
+        Map<VariableExpression, List<ClassNode>> oldTracker = 
pushAssignmentTracking();
         try {
-            super.visitTryCatchFinally(statement);
-        } finally {
-            for (CatchStatement catchStatement : catchStatements) {
-                
typeCheckingContext.controlStructureVariables.remove(catchStatement.getVariable());
+            visitStatement(statement);
+            statement.getResourceStatements().forEach(rsrc -> 
rsrc.visit(this));
+            statement.getTryStatement().visit(this);
+            for (CatchStatement catchStatement : 
statement.getCatchStatements()) {
+                vars.put(catchStatement.getVariable(), 
catchStatement.getExceptionType());
+                try {
+                    restoreTypeBeforeConditional();
+                    catchStatement.visit(this);
+                } finally {
+                    vars.remove(catchStatement.getVariable());
+                }
             }
+        } finally {
+            popAssignmentTracking(oldTracker);
         }
+        statement.getFinallyStatement().visit(this);
     }
 
     protected void storeType(final Expression exp, ClassNode cn) {
diff --git a/src/test/groovy/transform/stc/STCAssignmentTest.groovy 
b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
index fd7c636481..7d0efa5ed4 100644
--- a/src/test/groovy/transform/stc/STCAssignmentTest.groovy
+++ b/src/test/groovy/transform/stc/STCAssignmentTest.groovy
@@ -602,7 +602,7 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase {
         'Cannot find matching method java.io.Serializable#toInteger()'
     }
 
-    void testTernaryInitWithAssignment() {
+    void testTernaryWithNestedAssignment() {
         shouldFailWithMessages '''
             def x = '123'
             def y = (false ? (x = new HashSet()) : 42)
@@ -611,6 +611,35 @@ class STCAssignmentTest extends StaticTypeCheckingTestCase 
{
         'Cannot find matching method java.io.Serializable#toInteger()'
     }
 
+    // GROOVY-11457
+    void testTryCatchFinallyWithAssignment() {
+        assertScript '''
+            def x = (Appendable) null
+            if (true)  {
+                x = 1
+            }
+            try {
+                ;
+            } finally {
+                x = (Appendable) null
+            }
+            Appendable y = x
+        '''
+        shouldFailWithMessages '''
+            def x = (Appendable) null
+            if (true)  {
+                x = 1
+            }
+            try {
+                ;
+            } catch (e) {
+                x = (Appendable) null
+            }
+            Appendable y = x // Cannot cast object '1' with class 'Integer' to 
class 'Appendable'
+        ''',
+        'Cannot assign value of type java.lang.Object to variable of type 
java.lang.Appendable'
+    }
+
     void testFloatSub() {
         assertScript '''
             float x = 1.0f

Reply via email to