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