Prettyprint of Try-With-Resources Statement Broken

Issue #183 resolved
Georg Seibt created an issue

This pertains to the JAR built from commit 5eef0cc.

Broken code is produced when parsing and subsequently pretty-printing code that contains try-with-resources statements.

Input (see attachements):

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TWR {

    public static void main(String[] args) {

        try (FileOutputStream out = new FileOutputStream("out"); FileInputStream in = new FileInputStream("in")) {
            out.write(in.read());
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Execute:

java -cp extendj.jar org.extendj.JavaPrettyPrinter TWR.java

This gives the output (see attachments):

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

public class TWR {
  public static void main(String[] args) {
    try (out = new FileOutputStream("out")in = new FileInputStream("in")) {
      out.write(in.read());
    }
     catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

This code does not compile as the type declarations are missing in the resources declaration. The two resource declarations should also be separated by a semicolon. Additionally the linebreak after the closing brace of the try block is unexpected.

I looked at the code and the resource statements are represented by ResourceDeclaration instances whose prettyPrint method is defined in the Declarator class. The relevant part of Java4PrettyPrint.tt:

Declarator [[$ID$DimsList$if(hasInit) = $Init$endif]]

This of course can't produce the full FileOutputStream out = new FileOutputStream("out") declaration.

I would propose adding a ResourceDeclaration template for pretty printing and fixing the TryWithResources template. A corresponding pull request is forthcoming.

Comments (4)

  1. Jesper Öqvist

    Thank you for reporting this issue. I will add a test case for this to the regression suite. I see that you also made a pull request with a fix, I'll take a look at it soon.

    Thank you.

  2. Georg Seibt reporter

    For regression testing purposes I would also add a finally block to the example.

    Input:

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class TWR {
    
        public static void main(String[] args) {
    
            try (FileOutputStream out = new FileOutputStream("out"); FileInputStream in = new FileInputStream("in")) {
                out.write(in.read());
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                System.out.println("Hi!");
            }
        }
    }
    

    Output of 5eef0cc:

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class TWR {
      public static void main(String[] args) {
        try (out = new FileOutputStream("out")in = new FileInputStream("in")) {
          out.write(in.read());
        }
         catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        }
         finally {
          System.out.println("Hi!");
        }
      }
    }
    

    Output with the fixes I proposed in pull request #2:

    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    public class TWR {
      public static void main(String[] args) {
        try (FileOutputStream out = new FileOutputStream("out"); FileInputStream in = new FileInputStream("in")) {
          out.write(in.read());
        } catch (FileNotFoundException e) {
          e.printStackTrace();
        } catch (IOException e) {
          e.printStackTrace();
        } finally {
          System.out.println("Hi!");
        }
      }
    }
    
  3. Log in to comment