Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sorting usings #923

Merged
merged 17 commits into from
Oct 26, 2023
Merged

Sorting usings #923

merged 17 commits into from
Oct 26, 2023

Conversation

belav
Copy link
Owner

@belav belav commented Jul 1, 2023

closes #661

@belav belav marked this pull request as draft July 1, 2023 22:20
@belav belav force-pushed the sort-usings branch 3 times, most recently from 9878a55 to 1084567 Compare July 4, 2023 19:14
@belav belav marked this pull request as ready for review September 17, 2023 14:41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there should be some test cases for code that does crazy things with comments, for example:

// Licensed to something

using Microsoft.AspNetCore;
// I like putting
using Microsoft;
/*
 * random comments everywhere
 */
using Apple;
/* because it's valid C# code */
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
// Look mom, I'm using a really fancy authentication library:
using Microsoft.Identity.Web.UI;
using Microsoft.Identity.Web; // another comment just for good measure

I'm unsure how this case should be handled, these are the options I could think of:

  • Keep everything as is, whoever put a comment between the using statements probably has a good reason (Maybe show a warning when formatting? I am not familiar with this codebase so i'm not sure if showing warnings is even possible)
  • Sort the individual blocks of usings between the comments
  • Be opinionated and just remove the comments, lol

As far as I can tell tell it's impossible to sort usings with comments while preserving the original intent of the comments in all cases.

I don't really care what the final solution is, just that it's tested and works with all the possible comment formats.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping comments at the top was the only tricky part. Most comments are leading trivia which just goes with the node it is above. Trailing comments also stick with the node they are after. From all the code I reviewed, comments in usings aren't that common. #if is hard to deal with, but I have the basic cases covered. The .net analyzers themselves have some open issues around #ifs, so I'm not worried about the couple of edge cases that I couldn't resolve which appeared in the mono code.

// Licensed to something

/*
 * random comments everywhere
 */
using Apple;
// I like putting
using Microsoft;
using Microsoft.AspNetCore;
/* because it's valid C# code */
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.Identity.Web; // another comment just for good measure
// Look mom, I'm using a really fancy authentication library:
using Microsoft.Identity.Web.UI;


using First;
using Second;
B;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wtf is this?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe that was me going nuts trying comments everywhere a while back.
Apparently that is valid c#!

}
}

yield return globalUsings.OrderBy(o => o.Using!, Comparer).ToList();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need the null suppression operator for o.Using!?
.OrderBy() usually doesn't need it.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like because I was missing the ? on IComparer<UsingDirectiveSyntax?>

yield return globalUsings.OrderBy(o => o.Using!, Comparer).ToList();
yield return systemUsings.OrderBy(o => o.Using!, Comparer).ToList();
yield return aliasNameUsings.OrderBy(o => o.Using!, Comparer).ToList();
yield return regularUsings.OrderBy(o => o.Using!, Comparer).ToList();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suspect if you just do .OrderBy(o => "" + o.Using?.Alias.ToFullString() + o.Using?.Name.ToFullString()), you won't need that comparer.
Though it's long enough that it might be worth extracting to a helper method, and it might be slower because of the string concat, so 🤷

shocklateboy92
shocklateboy92 previously approved these changes Oct 26, 2023
Copy link
Collaborator

@shocklateboy92 shocklateboy92 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hate the a RawSyntaxKind is an extension method and not a property. Otherwise we could use awesome pattern matches in so many cool places.

@belav belav merged commit abdb40d into main Oct 26, 2023
3 checks passed
@belav belav deleted the sort-usings branch October 26, 2023 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Sorting of using directives
3 participants