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

Improve formatting of method will lot of parameters and with exception

Open murdos opened this issue 6 years ago • 12 comments

Source:

    public LoggingConfiguration(@Value("${spring.application.name}") String appName,
        @Value("${server.port}") String serverPort,
        JHipsterProperties jHipsterProperties,
        ObjectMapper mapper)
        throws JsonProcessingException {
        // ...
    }

Formatted with prettier 0.4.0:

    public LoggingConfiguration(
        @Value("${spring.application.name}") String appName,
        @Value("${server.port}") String serverPort,
        JHipsterProperties jHipsterProperties,
        ObjectMapper mapper
    )
        throws JsonProcessingException {
        // ...
    }

I'm not really sure what the result should be, but the position of ) after the last parameter is a bit strange in regards to the exception. Maybe:

    public LoggingConfiguration(
        @Value("${spring.application.name}") String appName,
        @Value("${server.port}") String serverPort,
        JHipsterProperties jHipsterProperties,
        ObjectMapper mapper
    ) throws JsonProcessingException {
        // ...
    }

murdos avatar Oct 20 '19 20:10 murdos

I agree with you. I am struggling with one case: how would you format the following ?

public void test() throws Exception1, Exception2, Exception3, Exception4, Exception5, Exception6 {}

Option 1:

public void test() 
    throws Exception1, Exception2, Exception3, Exception4, Exception5, Exception6 {}

Option 2:

public void test() throws 
    Exception1, Exception2, Exception3, Exception4, Exception5, Exception6 {}

Option 3:

public void test() throws Exception1, 
    Exception2, 
    Exception3, 
    Exception4, 
    Exception5, 
    Exception6 {}

Option 4:

public void test() throws 
    Exception1, 
    Exception2, 
    Exception3, 
    Exception4, 
    Exception5, 
    Exception6 {}

Option 5:

public void test() throws Exception1, Exception2, Exception3, Exception4, Exception5, Exception6 {}

clementdessoude avatar Oct 22 '19 09:10 clementdessoude

Does this formatting looks good ?

class T {
  public void test(String one, String one, String one, String one, String one, String one) {

  }

  public void test(String one, String one, String one, String one, String one, String one) throws Exception, Exception, Exception {

  }

  public void test(String one, String one, String one, String one, String one, String one) throws Exception {

  }

  public void test(String one, String one) throws Exception, Exception, Exception, Exception {

  }

  public void test() throws Exception1, Exception2, Exception3, Exception4, Exception5, Exception6 {

  }

  public void test(String one, String one) throws Exception {

  }
}

into

class T {

  public void test(
    String one,
    String one,
    String one,
    String one,
    String one,
    String one
  ) {}

  public void test(
    String one,
    String one,
    String one,
    String one,
    String one,
    String one
  ) throws Exception, Exception, Exception {}

  public void test(
    String one,
    String one,
    String one,
    String one,
    String one,
    String one
  ) throws Exception {}

  public void test(String one, String one) throws
    Exception,
    Exception,
    Exception,
    Exception {}

  public void test() throws
    Exception1,
    Exception2,
    Exception3,
    Exception4,
    Exception5,
    Exception6 {}

  public void test(String one, String one) throws Exception {}
}

clementdessoude avatar Oct 29 '19 15:10 clementdessoude

Outside perspective: Black (the Python formatter) does it like the prettier 0.4.0 example, so even if it doesn’t look great, it has precedence in the “code formatting” community.

NoahTheDuke avatar Oct 29 '19 16:10 NoahTheDuke

Sorry @clement26695 for the (very) late reply...

The best option IMO is to keep throws on the same line as the (first) exception(s), as in Option 1, because it's more readable (you don't have to look after the throws keyword that might be "hidden" at the end of the previous line) :


public void test() throws Exception1, Exception2 {}

public void test() 
    throws Exception1, Exception2, Exception3, Exception4, Exception5 {}

public void test(
    String one,
    String one,
    String one,
    String one,
    String one,
    String one
  ) throws Exception1, Exception2, Exception3, Exception4, Exception5 {}

This is consistent with how IntelliJ and Spotless (so probably Eclipse too) wrap the throws keyword: image

I'm just puzzled on the way to handle a long list of exceptions:

Option A

public void test() 
    throws Exception1, Exception2, Exception3, Exception4, Exception5, Exception6,
    Exception7 {}

public void test(
    String one,
    String one,
    String one,
    String one,
    String one,
    String one
  ) throws Exception1, Exception2, Exception3, Exception4, Exception5, Exception6,
    Exception7 {}

or

Option B

public void test() 
    throws Exception1, 
    Exception2, 
    Exception3, 
    Exception4, 
    Exception5, 
    Exception6,
    Exception7 {}

public void test(
    String one,
    String one,
    String one,
    String one,
    String one,
    String one
  ) throws Exception1, 
    Exception2, 
    Exception3, 
    Exception4, 
    Exception5, 
    Exception6,
    Exception7 {}

Option B is probably more consistent with the Prettier style.

murdos avatar Dec 03 '19 10:12 murdos

Just to confirm. The throws would have a double indent? If not, we would have the body of the method at the same indent label, for instance (with 0.4.0):

public OAuth1AccessToken getAccessToken(OAuth1RequestToken requestToken, String oauthVerifier)
    throws AuthenticationException {
    try {
        [...]
    }
}

benjavalero avatar Dec 03 '19 15:12 benjavalero

Just to confirm. The throws would have a double indent? If not, we would have the body of the method at the same indent label, for instance (with 0.4.0):

In my proposal, it would have a simple indent. I don't think it's a problem if we the same indent level for body and throws

murdos avatar Dec 08 '19 10:12 murdos

👍 the Option B style proposed here looks good to me https://github.com/jhipster/prettier-java/issues/286#issuecomment-561104810

jhaber avatar Dec 12 '19 14:12 jhaber

How about this:

public void one() throws Exc {
    doIt();
}

public void two(
    int someLongishArgument,
    int someOtherArgument
) throws Exc1, Exc2 {
    doIt();
}

public void three()
throws
    SomeWeirdExcpetion,
    SomeOtherWeirdException,
    SomeRatherRareException,
    SomeObscureException
{
    doIt();
}

public void four(
    int someLongishArgument,
    int someOtherArgument
) throws
    SomeWeirdExcpetion,
    SomeOtherWeirdException,
    SomeRatherRareException,
    SomeObscureException
{
    doIt();
}

digorydoo avatar Feb 15 '20 05:02 digorydoo

Hi @digorydoo, thank you for your feedbacks !

I definitively need to look at this. I'll try to work on this next week

clementdessoude avatar Feb 16 '20 15:02 clementdessoude

I'm sure this discussion has happened before, but I'm not finding it anywhere. I'm unclear as to why it puts every single element on a new line once it reaches the print width.

Given this:

public void test() throws Exception1, Exception2, Exception3, Exception4, Exception5, Exception6 {}

Why can't this be done?

public void test() throws Exception1, Exception2, Exception3, 
    Exception4, Exception5, Exception6 {

    //code here
}

OR

public void test() 
    throws Exception1, Exception2, Exception3, Exception4, 
        Exception5, Exception6 
{
    //code here
}

Same thing with method parameters.

public void methodName(int longArgument1,
    int longArgument2, int longArgument3,
    int longArgument4, int longArgument5
)

OR

public void methodName(
    int longArgument1, int longArgument2, 
    int longArgument3, int longArgument4, 
    int longArgument5
)

Essentially this: https://github.com/prettier/prettier/issues/6573 but for Java

MichielBugherJelli avatar May 06 '20 23:05 MichielBugherJelli

@MichielBugherJelli suggestion looks pretty good to me. Why keep every element to next line once reached print width. A smart wrap respecting print width value would be perfect.

sanjayrawat1 avatar Nov 13 '20 15:11 sanjayrawat1

Prettier is an opinionated formatter, and it seems like one of those opinions is that either all elements in a group should line break, or none should (and prettier-java inherits this behavior from prettier since it's a prettier plugin). The example above might look tidy because all of the arguments are the same type and happen to align nicely, but it quickly becomes text soup when that's not the case, for example:

public void doRemoteFetch(RemoteDataFetcher remoteDataFetcher,
    JsonDeserializer jsonDeserializer, CustomHeadersProvider customHeadersProvider,
    ResponseSignatureVerifier responseSignatureVerifier, ErrorHandlingStrategy errorHandlingStrategy
)

vs.

public void doRemoteFetch(
    RemoteDataFetcher remoteDataFetcher,
    JsonDeserializer jsonDeserializer, 
    CustomHeadersProvider customHeadersProvider,
    ResponseSignatureVerifier responseSignatureVerifier, 
    ErrorHandlingStrategy errorHandlingStrategy
)

But like I said before, this style is just an opinion so there's not much use in debating which way is objectively "right". However, this opinion is pretty much at the core of prettier and unlikely to change. If you don't like prettier's opinions, google-java-format might be of interest, it's another formatter that's a bit less opinionated and also has IDE plugins available.

jhaber avatar Nov 13 '20 15:11 jhaber