INRIA / INRIA/spoon

[Bug]: wrong output for try with resources (variable ends up several times in initializer list)

Open
#5,465 1 comment 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
2k
Forks
392
Avg merge
11h 24m
Merged PRs (30d)
36

Description

### Describe the bug

Spoon produces wrong output for try-with-resources without resource declaration. In the example, foo1() and bar1() that both contain a resource declaration produce correct results. The output for the other methods is incorrect, the variable should be present only once in the expression in parentheses.

Note that try-with-resources was changed in Java 9 to explicitly allow using final or effectively final variables in the try-with-resources list.

Actually I have another case, where `try (in) { ... }` gets transformed to the non-compilable `try { ... }`but I cannot reproduce with a simplified example, so I report these apparent failures first.

### Source code you are trying to analyze/transform

```Java
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;

class Issue {

public static void foo1() throws FileNotFoundException {
try (PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
writer.println("foo");
}
}

public static void bar1() throws FileNotFoundException {
try (PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
writer.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void foo2() throws FileNotFoundException {
PrintWriter writer = new PrintWriter(new File("testWrite.txt"));
try (writer) {
writer.println("foo");
}
}

public static void bar2() throws FileNotFoundException {
PrintWriter writer = new PrintWriter(new File("testWrite.txt"));
try (writer) {
writer.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void foo3(PrintWriter writer) throws FileNotFoundException {
try (writer) {
writer.println("foo");
}
}

public static void bar3(PrintWriter writer) throws FileNotFoundException {
try (writer) {
writer.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
}

}
```

### Source code for your Spoon processing

```Java
import spoon.Launcher;
import spoon.processing.AbstractProcessor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtType;

public class Main {
public static void main(String[] args) {
// Create and configure a Spoon launcher
Launcher launcher = new Launcher();
launcher.addProcessor(new NoOperationProcessor());
launcher.addInputResource("src/test/resources/Issue.java");
launcher.run();
launcher.getModel().getAllTypes().stream()
.map(CtType::toString)
.forEach(System.out::println);
}

// Create a no-operation processor
static class NoOperationProcessor extends AbstractProcessor {
@Override
public void process(CtElement element) {
// Do nothing
}
}
}
```

### Actual output

```Java
class Issue {
public static void foo1() throws java.io.FileNotFoundException {
try (java.io.PrintWriter writer = new java.io.PrintWriter(new java.io.File("testWrite.txt"))) {
writer.println("foo");
}
}

public static void bar1() throws java.io.FileNotFoundException {
try (java.io.PrintWriter writer = new java.io.PrintWriter(new java.io.File("testWrite.txt"))) {
writer.println("bar");
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}

public static void foo2() throws java.io.FileNotFoundException {
java.io.PrintWriter writer = new java.io.PrintWriter(new java.io.File("testWrite.txt"));
try (writer;writer;writer) {
writer.println("foo");
}
}

public static void bar2() throws java.io.FileNotFoundException {
java.io.PrintWriter writer = new java.io.PrintWriter(new java.io.File("testWrite.txt"));
try (writer;writer;writer) {
writer.println("bar");
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}

public static void foo3(java.io.PrintWriter writer) throws java.io.FileNotFoundException {
try (writer;writer) {
writer.println("foo");
}
}

public static void bar3(java.io.PrintWriter writer) throws java.io.FileNotFoundException {
try (writer;writer) {
writer.println("bar");
} catch (java.lang.Exception e) {
e.printStackTrace();
}
}
}
```

### Expected output

```Java
import java.io.File;
import java.io.FileNotFoundException;
import java.io.PrintWriter;

class Issue {

public static void foo1() throws FileNotFoundException {
try (PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
writer.println("foo");
}
}

public static void bar1() throws FileNotFoundException {
try (PrintWriter writer = new PrintWriter(new File("testWrite.txt"))) {
writer.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void foo2() throws FileNotFoundException {
PrintWriter writer = new PrintWriter(new File("testWrite.txt"));
try (writer) {
writer.println("foo");
}
}

public static void bar2() throws FileNotFoundException {
PrintWriter writer = new PrintWriter(new File("testWrite.txt"));
try (writer) {
writer.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
}

public static void foo3(PrintWriter writer) throws FileNotFoundException {
try (writer) {
writer.println("foo");
}
}

public static void bar3(PrintWriter writer) throws FileNotFoundException {
try (writer) {
writer.println("bar");
} catch (Exception e) {
e.printStackTrace();
}
}

}
```

### Spoon Version

10.4.1

### JVM Version

17

### What operating system are you using?

macOS Ventura 13.5.2

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.