1+ /* This file is part of KeY - https://key-project.org
2+ * KeY is licensed under the GNU General Public License Version 2
3+ * SPDX-License-Identifier: GPL-2.0-only */
14package de .uka .ilkd .key .java .transformations .pipeline ;
25
6+ import java .util .List ;
7+ import java .util .concurrent .atomic .AtomicInteger ;
8+
39import com .github .javaparser .ast .NodeList ;
410import com .github .javaparser .ast .body .Parameter ;
511import com .github .javaparser .ast .body .TypeDeclaration ;
1016import com .github .javaparser .ast .visitor .ModifierVisitor ;
1117import com .github .javaparser .ast .visitor .Visitable ;
1218
13- import java .util .List ;
14- import java .util .concurrent .atomic .AtomicInteger ;
15-
1619/// Rewrites every try-with-resources statement into the equivalent nested
1720/// try/finally form that javac itself generates, i.e. for
1821/// ```java
1922/// try (Resource r = open()) {
20- /// body;
23+ /// body;
2124/// }
2225/// ```
2326/// this produces:
2427/// ```java
2528/// try {
26- /// Resource r = open();
27- /// Throwable primaryExc$1 = null;
28- /// try {
29- /// body;
30- /// } catch (Throwable t$1) {
31- /// primaryExc$1 = t$1;
32- /// throw t$1;
33- /// } finally {
34- /// if (r != null) {
35- /// if (primaryExc$1 != null) {
36- /// try { r.close(); } catch (Throwable suppressedExc$1) {
37- /// primaryExc$1.addSuppressed(suppressedExc$1);
38- /// }
39- /// } else { r.close(); }
40- /// }
41- /// }
29+ /// Resource r = open();
30+ /// Throwable primaryExc$1 = null;
31+ /// try {
32+ /// body;
33+ /// } catch (Throwable t$1) {
34+ /// primaryExc$1 = t$1;
35+ /// throw t$1;
36+ /// } finally {
37+ /// if (r != null) {
38+ /// if (primaryExc$1 != null) {
39+ /// try { r.close(); } catch (Throwable suppressedExc$1) {
40+ /// primaryExc$1.addSuppressed(suppressedExc$1);
41+ /// }
42+ /// } else { r.close(); }
43+ /// }
44+ /// }
4245/// }
4346/// ```
4447/// Multiple resources are handled by nesting (last-declared resource closes first),
4548/// and any catch/finally clauses that were attached to the original try are kept
4649/// on an outer try that wraps the whole resource-management block, exactly as
4750/// javac does it.
51+ ///
4852/// @author weigl, Claude Sonnet
4953public class TryWithResourceReducer implements JavaTransformer {
5054 private final AtomicInteger counter = new AtomicInteger ();
@@ -91,18 +95,17 @@ private BlockStmt desugarResources(List<Expression> resources, int index, BlockS
9195 BlockStmt result = new BlockStmt ();
9296
9397 Expression resourceExpr = resources .get (index );
94- String resourceName ;
98+ Expression resourceName ;
9599
96- if (resourceExpr instanceof VariableDeclarationExpr ) {
100+ if (resourceExpr instanceof VariableDeclarationExpr vde ) {
97101 // try (Resource r = new Resource()) { ... }
98- VariableDeclarationExpr vde = (VariableDeclarationExpr ) resourceExpr ;
99102 VariableDeclarator vd = vde .getVariable (0 );
100- resourceName = vd .getNameAsString ();
103+ resourceName = vd .getNameAsExpression ();
101104 result .addStatement (new ExpressionStmt (vde .clone ()));
102105 } else {
103106 // Java 9+ form: try (existingEffectivelyFinalVar) { ... }
104107 // No declaration needed -- the variable already exists in scope.
105- resourceName = resourceExpr . toString () ;
108+ resourceName = resourceExpr ;
106109 }
107110
108111 int id = counter .incrementAndGet ();
@@ -118,14 +121,17 @@ private BlockStmt desugarResources(List<Expression> resources, int index, BlockS
118121
119122 // catch (Throwable t$n) { primaryExc$n = t$n; throw t$n; }
120123 CatchClause catchClause = new CatchClause ();
121- catchClause .setParameter (new Parameter (new ClassOrInterfaceType (null , "Throwable" ), throwableName ));
124+ catchClause .setParameter (
125+ new Parameter (new ClassOrInterfaceType (null , "Throwable" ), throwableName ));
122126 BlockStmt catchBody = new BlockStmt ();
123127 catchBody .addStatement (new ExpressionStmt (
124- new AssignExpr (new NameExpr (primaryExcName ), new NameExpr (throwableName ), AssignExpr .Operator .ASSIGN )));
128+ new AssignExpr (new NameExpr (primaryExcName ), new NameExpr (throwableName ),
129+ AssignExpr .Operator .ASSIGN )));
125130 catchBody .addStatement (new ThrowStmt (new NameExpr (throwableName )));
126131 catchClause .setBody (catchBody );
127132
128- // finally { if (r != null) { if (primaryExc$n != null) { try { r.close(); } catch (Throwable s) { primaryExc$n.addSuppressed(s); } } else { r.close(); } } }
133+ // finally { if (r != null) { if (primaryExc$n != null) { try { r.close(); } catch
134+ // (Throwable s) { primaryExc$n.addSuppressed(s); } } else { r.close(); } } }
129135 BlockStmt finallyBlock = new BlockStmt ();
130136
131137 IfStmt excCheck = new IfStmt ();
@@ -137,10 +143,12 @@ private BlockStmt desugarResources(List<Expression> resources, int index, BlockS
137143 closeWithSuppression .setTryBlock (closeTryBlock );
138144
139145 CatchClause suppressCatch = new CatchClause ();
140- suppressCatch .setParameter (new Parameter (new ClassOrInterfaceType (null , "Throwable" ), suppressedExcName ));
146+ suppressCatch .setParameter (
147+ new Parameter (new ClassOrInterfaceType (null , "Throwable" ), suppressedExcName ));
141148 BlockStmt suppressBody = new BlockStmt ();
142149 suppressBody .addStatement (new ExpressionStmt (new MethodCallExpr (
143- new NameExpr (primaryExcName ), "addSuppressed" , NodeList .nodeList (new NameExpr (suppressedExcName )))));
150+ new NameExpr (primaryExcName ), "addSuppressed" ,
151+ NodeList .nodeList (new NameExpr (suppressedExcName )))));
144152 suppressCatch .setBody (suppressBody );
145153 closeWithSuppression .setCatchClauses (NodeList .nodeList (suppressCatch ));
146154
@@ -151,7 +159,7 @@ private BlockStmt desugarResources(List<Expression> resources, int index, BlockS
151159 excCheck .setElseStmt (plainClose );
152160
153161 IfStmt nullCheck = new IfStmt ();
154- nullCheck .setCondition (notNull (new NameExpr ( resourceName )));
162+ nullCheck .setCondition (notNull (resourceName . clone ( )));
155163 BlockStmt nullCheckThen = new BlockStmt ();
156164 nullCheckThen .addStatement (excCheck );
157165 nullCheck .setThenStmt (nullCheckThen );
@@ -171,13 +179,15 @@ private static BinaryExpr notNull(Expression e) {
171179 return new BinaryExpr (e , new NullLiteralExpr (), BinaryExpr .Operator .NOT_EQUALS );
172180 }
173181
174- private static MethodCallExpr closeCall (String resourceName ) {
175- return new MethodCallExpr (new NameExpr ( resourceName ), "close" );
182+ private static MethodCallExpr closeCall (Expression resourceName ) {
183+ return new MethodCallExpr (resourceName . clone ( ), "close" );
176184 }
177185
178- private static Statement declareVar (String typeName , String varName , Expression initializer ) {
179- VariableDeclarator vd = new VariableDeclarator (new ClassOrInterfaceType (null , typeName ), varName , initializer );
186+ private static Statement declareVar (String typeName , String varName ,
187+ Expression initializer ) {
188+ VariableDeclarator vd = new VariableDeclarator (new ClassOrInterfaceType (null , typeName ),
189+ varName , initializer );
180190 return new ExpressionStmt (new VariableDeclarationExpr (vd ));
181191 }
182192 }
183- }
193+ }
0 commit comments