prettier-java icon indicating copy to clipboard operation
prettier-java copied to clipboard

fix: stable format for if/for/while/do/catch/switch with trailing comment

Open jtkiesel opened this issue 1 year ago • 4 comments

What changed with this PR:

If/for/while/do/catch/switch statements whose parentheses have trailing comments are now formatted stably, and in general are formatted more closely to the way that Prettier JavaScript does.

Example

Input

class Example {

  void ifStatements() {
    if (true) // comment
      System.out.println("Oops");

    if (true) {
      // comment
    }

    if (true) // comment
    {}

    if (true) // comment
    {
      System.out.println("Oops");
    }

    if (true) // comment
    {
      if (true) {}
    }

    if (true) // comment
    ;

    if (true) /*comment*/;
  }

  void forLoops() {
    for (int i = 0; i < 1; i++) // comment
      System.out.println("Oops");

    for (int i = 0; i < 1; i++) {
      // comment
    }

    for (;;)/*comment*/;

    for (int i = 0;;) //comment
    ;

    for (int i = 0; i < 1;) // comment
    {}

    for (;;) // comment
    {}

    for (; i < 1;) // comment
    {}

    for (;; i++) // comment
    {}

    for (
      int i = 0;
      i < 1;
      i++ // hi
    ) // comment
    {
      System.out.println("Oops");
    }

    for (int i = 0; i < 1; i++) // comment
    {
      if (true) {}
    }

    for (int i = 0; i < 1; i++) /*comment*/;

    for (String s : strings) // comment
      System.out.println("Oops");

    for (String s : strings) {
      // comment
    }

    for (String s : strings) // comment
    {}

    for (
      String s : strings // comment
    ) {}

    for (String s : strings) // comment
    {
      System.out.println("Oops");
    }

    for (String s : strings) // comment
    {
      if (true) {}
    }
  }

  void whileLoops() {
    while (true) // comment
      System.out.println("Oops");

    while (true) {
      // comment
    }

    while (true) // comment
    {}

    while (true) // comment
    {
      System.out.println("Oops");
    }

    while (
      true // test
    ) // comment
    {
      if (true) {}
    }

    while (true) // comment
    ;

    while (true) /*comment*/;
  }

  void doLoops() {
    do {
      // comment
    } while (true);

    do // comment
    {} while (true);

    do // comment
    {
      System.out.println("Oops");
    } while (true);

    do // comment
    {
      if (true) {}
    } while (true);

    do {} while (true) // comment
    ;

    do {} while (true) /*comment*/;

    do {
      System.out.println("Oops");
    } while (true) // comment
    ;

    do {
      if (true) {}
    } while (true) // comment
    ;
  }

  void switchStatements() {
    switch (value) {
      // comment
    }

    switch (value) // comment
    {}

    switch (value) // comment
    {
      case "a":
        System.out.println("Oops");
    }
  }

  void catchStatements() {
    try {} catch (Exception e) {
      // comment
    }

    try {} catch (Exception e) // comment
    {}

    try {} catch (Exception e) // comment
    {
      System.out.println("Oops");
    }

    try {} catch (Exception e) // comment
    {
      if (true) {}
    }
  }
}

Output

class Example {

  void ifStatements() {
    if (true)
      // comment
      System.out.println("Oops");

    if (true) {
      // comment
    }

    if (true) {
      // comment
    }

    if (true) {
      // comment
      System.out.println("Oops");
    }

    if (true) {
      // comment
      if (true) {}
    }

    if (
      true // comment
    );

    if (true/*comment*/);
  }

  void forLoops() {
    for (
      int i = 0;
      i < 1;
      i++ // comment
    )
      System.out.println("Oops");

    for (int i = 0; i < 1; i++) {
      // comment
    }

    /*comment*/
    for (;;);

    for (
      int i = 0; //comment
      ;

    );

    for (
      int i = 0;
      i < 1; // comment

    ) {}

    // comment
    for (;;) {}

    for (
      ;
      i < 1; // comment

    ) {}

    for (
      ;
      ;
      i++ // comment
    ) {}

    for (
      int i = 0;
      i < 1;
      i++ // hi
      // comment
    ) {
      System.out.println("Oops");
    }

    for (
      int i = 0;
      i < 1;
      i++ // comment
    ) {
      if (true) {}
    }

    for (int i = 0; i < 1; i++/*comment*/);

    for (String s : strings)
      // comment
      System.out.println("Oops");

    for (String s : strings) {
      // comment
    }

    for (String s : strings) {
      // comment
    }

    for (String s : strings) {} // comment

    for (String s : strings) {
      // comment
      System.out.println("Oops");
    }

    for (String s : strings) {
      // comment
      if (true) {}
    }
  }

  void whileLoops() {
    while (true)
      // comment
      System.out.println("Oops");

    while (true) {
      // comment
    }

    while (true) {
      // comment
    }

    while (true) {
      // comment
      System.out.println("Oops");
    }

    while (
      true // test
    ) {
      // comment
      if (true) {}
    }

    while (
      true // comment
    );

    while (true/*comment*/);
  }

  void doLoops() {
    do {
      // comment
    } while (true);

    do {} while (true); // comment

    do { // comment
      System.out.println("Oops");
    } while (true);

    do { // comment
      if (true) {}
    } while (true);

    do {} while (
      true // comment
    );

    do {} while (true/*comment*/);

    do {
      System.out.println("Oops");
    } while (
      true // comment
    );

    do {
      if (true) {}
    } while (
      true // comment
    );
  }

  void switchStatements() {
    switch (value) {
      // comment
    }

    switch (
      value // comment
    ) {}

    switch (
      value // comment
    ) {
      case "a":
        System.out.println("Oops");
    }
  }

  void catchStatements() {
    try {} catch (Exception e) {
      // comment
    }

    try {} catch (
      Exception e // comment
    ) {}

    try {} catch (
      Exception e // comment
    ) {
      System.out.println("Oops");
    }

    try {} catch (
      Exception e // comment
    ) {
      if (true) {}
    }
  }
}

Relative issues or prs:

Closes #592

jtkiesel avatar Aug 06 '23 02:08 jtkiesel

Thank you, @jtkiesel ! It seems that quite a lot of logic is added in order to handle this edge case. I would like to dig a bit more into the issue to see if we can simplify some things before merging this. My objective would be to look at it by the end of the week (and the other pending PR) so we could release a new version of Prettier this weekend :)

clementdessoude avatar Aug 15 '23 20:08 clementdessoude

I looked at it more closely yesterday, but was not able to wrap it up, sorry. I propose to make a new release with the changes that were made since 2.2.0 (https://github.com/jhipster/prettier-java/pull/600), and finish this afterwards.

clementdessoude avatar Aug 21 '23 07:08 clementdessoude

Sounds good! I'll try to take another look at it this week as well, and see if I can simplify it at all.

jtkiesel avatar Aug 21 '23 15:08 jtkiesel

@clementdessoude @jtkiesel Did you find time to look into this? 😇

koppor avatar Nov 17 '23 11:11 koppor