66import com .github .javaparser .ast .body .VariableDeclarator ;
77import com .github .javaparser .ast .expr .*;
88import com .github .javaparser .ast .stmt .TryStmt ;
9+ import com .github .javaparser .ast .type .VarType ;
910import com .github .javaparser .resolution .UnsolvedSymbolException ;
11+ import com .github .javaparser .resolution .types .ResolvedType ;
1012import io .codemodder .Either ;
1113import io .codemodder .ast .*;
1214import java .util .ArrayDeque ;
@@ -168,9 +170,29 @@ public static ObjectCreationExpr findRootExpression(final ObjectCreationExpr cre
168170 return current ;
169171 }
170172
173+ private static String generateNameWithSuffix (final Expression start ) {
174+ var root = rootPrefix ;
175+ try {
176+ var typeName = start .calculateResolvedType ().describe ();
177+ typeName = typeName .substring (typeName .lastIndexOf ('.' ) + 1 );
178+ typeName = Character .toLowerCase (typeName .charAt (0 )) + typeName .substring (1 );
179+ root = typeName ;
180+ } catch (RuntimeException e ) {
181+ root = rootPrefix ;
182+ }
183+ var maybeName = ASTs .findNonCallableSimpleNameSource (start , root );
184+ int count = 0 ;
185+ String nameWithSuffix = root ;
186+ while (maybeName .isPresent ()) {
187+ count ++;
188+ nameWithSuffix = root + count ;
189+ maybeName = ASTs .findNonCallableSimpleNameSource (start , nameWithSuffix );
190+ }
191+ return count == 0 ? root : nameWithSuffix ;
192+ }
193+
171194 public static Optional <TryStmt > tryToFix (final ObjectCreationExpr creationExpr ) {
172195 final var deque = findInnerExpressions (creationExpr );
173- int count = 0 ;
174196 final var maybeLVD =
175197 ASTs .isInitExpr (creationExpr )
176198 .flatMap (LocalVariableDeclaration ::fromVariableDeclarator )
@@ -188,26 +210,18 @@ public static Optional<TryStmt> tryToFix(final ObjectCreationExpr creationExpr)
188210 maybeLVD .get ().getScope ());
189211 var cu = creationExpr .findCompilationUnit ().get ();
190212 for (var resource : deque ) {
191- var name = count == 0 ? rootPrefix : rootPrefix + count ;
192- // TODO try to resolve type, failing to do that use var declaration?
193- var type = resource .calculateResolvedType ().describe ();
194- resource .replace (new NameExpr (name ));
195-
196- var declaration =
197- new VariableDeclarator (
198- StaticJavaParser .parseType (type .substring (type .lastIndexOf ('.' ) + 1 )),
199- name ,
200- resource );
201- tryStmt .getResources ().addFirst (new VariableDeclarationExpr (declaration ));
202- ASTTransforms .addImportIfMissing (cu , type );
203- count ++;
213+ var typeName = calculateResolvedType (resource ).map (rt -> rt .describe ());
214+ tryStmt
215+ .getResources ()
216+ .addFirst (new VariableDeclarationExpr (buildDeclaration (resource , typeName )));
217+ typeName .ifPresent (tn -> ASTTransforms .addImportIfMissing (cu , tn ));
204218 }
205219 return Optional .of (tryStmt );
206220 }
207221 return Optional .empty ();
208222 }
209223
210- /** Tries to fix the leak of {@code expr} and returns its line if it does. */
224+ /** Tries to fix the leak of {@code expr} and returns line if it does. */
211225 public static Optional <TryStmt > tryToFix (final MethodCallExpr mce ) {
212226
213227 // Is LocalDeclarationStmt and Never Assigned -> Wrap as a try resource
@@ -228,24 +242,13 @@ public static Optional<TryStmt> tryToFix(final MethodCallExpr mce) {
228242 var tryStmt =
229243 ASTTransforms .wrapIntoResource (
230244 lvd .getStatement (), lvd .getVariableDeclarationExpr (), lvd .getScope ());
231- // TODO check availability here
232- int count = 0 ;
233245 var cu = mce .findCompilationUnit ().get ();
234246 for (var resource : resources ) {
235- var name = count == 0 ? rootPrefix : rootPrefix + count ;
236- // TODO try to resolve type, failing to do that use var declaration?
237- var type = resource .calculateResolvedType ().describe ();
238-
239- resource .replace (new NameExpr (name ));
240-
241- var declaration =
242- new VariableDeclarator (
243- StaticJavaParser .parseType (type .substring (type .lastIndexOf ('.' ) + 1 )),
244- name ,
245- resource );
246- tryStmt .getResources ().addFirst (new VariableDeclarationExpr (declaration ));
247- ASTTransforms .addImportIfMissing (cu , type );
248- count ++;
247+ var typeName = calculateResolvedType (resource ).map (rt -> rt .describe ());
248+ tryStmt
249+ .getResources ()
250+ .addFirst (new VariableDeclarationExpr (buildDeclaration (resource , typeName )));
251+ typeName .ifPresent (tn -> ASTTransforms .addImportIfMissing (cu , tn ));
249252 }
250253 return Optional .of (tryStmt );
251254 // TODO if vde is multiple declarations, extract the relevant vd and wrap it
@@ -254,6 +257,27 @@ public static Optional<TryStmt> tryToFix(final MethodCallExpr mce) {
254257 return Optional .empty ();
255258 }
256259
260+ private static Optional <ResolvedType > calculateResolvedType (final Expression e ) {
261+ try {
262+ return Optional .of (e .calculateResolvedType ());
263+ } catch (final RuntimeException exception ) {
264+ return Optional .empty ();
265+ }
266+ }
267+
268+ private static VariableDeclarator buildDeclaration (
269+ final Expression resource , final Optional <String > typeName ) {
270+ var name = generateNameWithSuffix (resource );
271+ resource .replace (new NameExpr (name ));
272+ return new VariableDeclarator (
273+ typeName .isPresent ()
274+ ? StaticJavaParser .parseType (
275+ typeName .get ().substring (typeName .get ().lastIndexOf ('.' ) + 1 ))
276+ : new VarType (),
277+ name ,
278+ resource );
279+ }
280+
257281 private static Deque <Expression > findInnerExpressions (final ObjectCreationExpr creationExpr ) {
258282 var deque = new ArrayDeque <Expression >();
259283 var maybeExpr =
0 commit comments