Skip to content

Commit

Permalink
Initial work for sorting usings
Browse files Browse the repository at this point in the history
closes #661
  • Loading branch information
belav committed Jul 1, 2023
1 parent b70ef6d commit ba56222
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 13 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using System;

#if DEBUG
using Insite.Bad;
#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#if DEBUG
using Insite.Bad;
#endif
using System;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using AWord;
using BWord;
using MWord;
using YWord;
using ZWord;
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using MWord;
using ZWord;
using AWord;
using BWord;
using YWord;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System;

using System.Web; // keeping the space above this is odd, but there isn't a good way to know which spaces to remove besides the first one

using AWord;
using ZWord;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using ZWord;

using AWord; // the blank line above here tests that we don't add two blank lines between system and non-system

using System.Web; // keeping the blank line above this in the expected is odd, but there isn't a good way to know which spaces to remove besides the first one
using System;
14 changes: 1 addition & 13 deletions Src/CSharpier/SyntaxPrinter/NamespaceLikePrinter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,7 @@ FormattingContext context
docs.Add(Doc.HardLine);
}

docs.Add(
Doc.Join(
Doc.HardLine,
usings.Select(
(o, i) =>
UsingDirective.Print(
o,
context,
printExtraLines: i != 0 || externs.Count != 0
)
)
)
);
docs.Add(UsingDirectives.PrintWithSorting(usings, context, externs.Count != 0));
}

var isCompilationUnitWithAttributes = false;
Expand Down
104 changes: 104 additions & 0 deletions Src/CSharpier/SyntaxPrinter/UsingDirectives.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
namespace CSharpier.SyntaxPrinter;

internal static class UsingDirectives
{
private static readonly DefaultOrder Comparer = new();

// TODO what does the analyzer do with some of these sorts?
// TODO what about validation?
// TODO what about #ifs?
// TODO what about globals?
// TODO what about statics?
// TODO what about alias?
// TODO get rid of lines and keep them in blocks? - this does https://google.github.io/styleguide/javaguide.html#s3.3-import-statements
// TODO what about alias any type with c# 12?

public static Doc PrintWithSorting(
SyntaxList<UsingDirectiveSyntax> usings,
FormattingContext context,
bool printExtraLines
)
{
var sortedUsings = usings.OrderBy(o => o, Comparer).ToArray();
var docs = new List<Doc>();

var lastWasSystem = false;
for (var i = 0; i < sortedUsings.Length; i++)
{
var noExtraLines = false;
var thisIsSystem = sortedUsings[i].Name is NameSyntax name && IsSystemName(name);
if (i != 0)
{
docs.Add(Doc.HardLine);
if (!thisIsSystem && lastWasSystem)
{
noExtraLines = true;
docs.Add(Doc.HardLine);
}

lastWasSystem = thisIsSystem;
}
docs.Add(
UsingDirective.Print(
sortedUsings[i],
context,
printExtraLines: (i != 0 || printExtraLines) && !noExtraLines
)
);
}

return Doc.Concat(docs);
}

private static bool IsSystemName(NameSyntax value)
{
while (true)
{
if (value is not QualifiedNameSyntax qualifiedNameSyntax)
{
return value is IdentifierNameSyntax { Identifier.Text: "System" };
}
value = qualifiedNameSyntax.Left;
}
}

private class DefaultOrder : IComparer<UsingDirectiveSyntax>
{
public int Compare(UsingDirectiveSyntax? x, UsingDirectiveSyntax? y)
{
if (x?.Name is null)
{
return -1;
}

if (y?.Name is null)
{
return 1;
}

var xIsSystem = IsSystemName(x.Name);
var yIsSystem = IsSystemName(y.Name);

int Return(int value)
{
DebugLogger.Log(
$"{x.ToFullString().Trim()} {xIsSystem} vs {y.ToFullString().Trim()} {yIsSystem} = {value}"
);

return value;
}

if (xIsSystem && !yIsSystem)
{
return Return(-1);
}

if (!xIsSystem && yIsSystem)
{
return Return(1);
}

return Return(x.Name.ToFullString().CompareTo(y.Name.ToFullString()));
}
}
}

0 comments on commit ba56222

Please sign in to comment.