google-java-format icon indicating copy to clipboard operation
google-java-format copied to clipboard

Block-like array initializers are not preserved

Open makinako opened this issue 4 years ago • 3 comments

The Google Java Style Guide specifies that arrays may be formatted in a block-like fashion, however google-java-format clobbers this to one line per element.

For example, the following:

protected static final byte[] TEST_ARRAY =
      new byte[] {
        (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0xFF, (byte) 0xFF
      };

becomes

  protected static final byte[] TEST_ARRAY =
      new byte[] {
        (byte) 0x31,
        (byte) 0x32,
        (byte) 0x33,
        (byte) 0x34,
        (byte) 0x35,
        (byte) 0x36,
        (byte) 0xFF,
        (byte) 0xFF
      };

For larger formatted constant definitions, formatting is essential to preserving understanding of the structure. It seems like preserving formatting should either be default behaviour, or an option.

makinako avatar Mar 09 '21 01:03 makinako

The original formatting exceeds the column limit, and the formatter doesn't introduce block or grid-like layouts, but if you manually reformat that into a grid the formatter will preserve that grid-like layout when it runs.

$ google-java-format T.java
class T {
  protected static final byte[] TEST_ARRAY = {
    (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34,
    (byte) 0x35, (byte) 0x36, (byte) 0xFF, (byte) 0xFF
  };
}

(This is one of the few places the formatter preserves existing formatting decisions, instead of ignoring existing whitespace when making formatting decisions.)

cushon avatar Mar 09 '21 01:03 cushon

Yes in that case that makes total sense! There seems to be a bit more to this though. When I looked at what was happening in my code, I saw that some of my arrays (that were <100 chars) were indented by a mix of tabs and spaces, not just spaces.

See the following:

public class Main {

  protected static final byte[] TEST_ARRAY_TABS =
	new byte[] {
		(byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, 
		(byte) 0x35, (byte) 0x36, (byte) 0xFF, (byte) 0xFF
      };

  protected static final byte[] TEST_ARRAY_SPACES =
    new byte[] {
      (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, 
      (byte) 0x35, (byte) 0x36, (byte) 0xFF, (byte) 0xFF
      };

  protected static final byte[] TEST_ARRAY_TABS_AND_SPACES =
    new byte[] {
        (byte) 0x31, (byte) 0x32, (byte) 0x33, (byte) 0x34, 
	(byte) 0x35, (byte) 0x36, (byte) 0xFF, (byte) 0xFF
      };

}

The first two remain intact, the third reformats to one-per-line. This makes it easy to avoid the problem, but I suspect the expected behaviour should be that the tabs are converted to spaces and the block formatting is preserved in the third case.

makinako avatar Mar 09 '21 02:03 makinako