dangmai / prettier-plugin-apex

Code formatter for the Apex Programming Language
https://apex.dangmai.net
MIT License
256 stars 45 forks source link

Line Breaks off of Static Queries in a SObject Constructor #319

Open kacrouse opened 3 years ago

kacrouse commented 3 years ago
# Prettier options (if any):
none

Input:

Contact newContact = new Contact(FirstName = 'test', LastName = 'contact', AccountId = [SELECT Id FROM Account LIMIT 1].Id);

Actual output:

Contact newContact = new Contact(
    FirstName = 'test',
    LastName = 'contact',
    AccountId = [SELECT Id FROM Account LIMIT 1]
    .Id
);

Expected output:

Contact newContact = new Contact(
    FirstName = 'test',
    LastName = 'contact',
    AccountId = [SELECT Id FROM Account LIMIT 1].Id
);

Even if the query was longer to where it needed to be split across multiple lines, I still think the .Id should not be on its own line.

Additional information (please fill this out):

dangmai commented 3 years ago

Thanks for the bug report, I agree that the current format does not look right, but we need to think a bit more about the expected output. For example, what if the property chain after the SOQL query is really long, like this:

Contact newContact = new Contact(
    FirstName = 'test',
    LastName = 'contact',
    AccountId = [SELECT Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id FROM Test_Object__c LIMIT 1].Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id
);

In my mind it makes sense to format it this way:

Contact newContact = new Contact(
    FirstName = 'test',
    LastName = 'contact',
    AccountId = [SELECT Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id FROM Test_Object__c LIMIT 1]
      .Another_Test_Object__r
      .Yet_Another_Test_Object__r
      .Account
      .Id
);

Maybe we should allow breaking it up if there are more than 1 property in the chain, but keep it on the same line if there's only 1. This is very early thought from me though, I have to dive deep into the current implementation to see what it's doing, and how complicated it would be to add this type of behavior.

kacrouse commented 3 years ago

You're right, it gets tricky if there is a long query and a long chain of properties. I can't see a good way to break up both the query and the property chain across lines. This might be another option for formatting it. I think the query is likely to be longer than the property chain, so this approach might look better in a larger number of scenarios?

Contact newContact = new Contact(
    FirstName = 'test',
    LastName = 'contact',
    AccountId = [
        SELECT Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id 
        FROM Test_Object__c 
        LIMIT 1
    ].Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id
);

Or to get even more complex...

That sounds like it might be a pain to implement 😅

kacrouse commented 3 years ago

You may be aware already, but I just realized this issue applies to all static queries, not just those in an SObject constructor. Example below.

Input

[SELECT Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id FROM Test_Object__c LIMIT 1].Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id;

Output

[SELECT Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id FROM Test_Object__c LIMIT 1]
.Another_Test_Object__r.Yet_Another_Test_Object__r.Account.Id;