Skip to content

Commit

Permalink
Merge branch 'main' into ditch-line-in-no-braces
Browse files Browse the repository at this point in the history
  • Loading branch information
belav authored Nov 1, 2023
2 parents ea2f314 + 622dae4 commit ebf21c6
Show file tree
Hide file tree
Showing 19 changed files with 110 additions and 34 deletions.
1 change: 1 addition & 0 deletions Src/CSharpier.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public void Default_SyntaxNodeComparer()
this.code,
this.code,
false,
false,
CancellationToken.None
);
syntaxNodeComparer.CompareSource();
Expand Down
3 changes: 2 additions & 1 deletion Src/CSharpier.Cli/CommandLineFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,8 @@ CancellationToken cancellationToken
var syntaxNodeComparer = new SyntaxNodeComparer(
fileToFormatInfo.FileContents,
codeFormattingResult.Code,
codeFormattingResult.IgnoreDisabledText,
codeFormattingResult.ReorderedModifiers,
codeFormattingResult.ReorderedUsingsWithDisabledText,
cancellationToken
);

Expand Down
2 changes: 1 addition & 1 deletion Src/CSharpier.Cli/EditorConfig/ConfigFileParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal static class ConfigFileParser
private static readonly Regex CommentRegex = new("^[;#].*$");

private static readonly IniParserConfiguration Configuration =
new() { CommentRegex = CommentRegex, };
new() { CommentRegex = CommentRegex, AllowDuplicateKeys = true };

public static ConfigFile Parse(string filePath, IFileSystem fileSystem)
{
Expand Down
47 changes: 35 additions & 12 deletions Src/CSharpier.FakeGenerators/SyntaxNodeComparerGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ private static string GenerateSource()
{
var sourceBuilder = new StringBuilder();
sourceBuilder.AppendLine(
@"#pragma warning disable CS0168
"""
#pragma warning disable CS0168
using System;
using System.Linq;
using Microsoft.CodeAnalysis;
Expand Down Expand Up @@ -58,7 +59,8 @@ private CompareResult Compare(
}
switch (originalNode)
{"
{
"""
);

var syntaxNodeTypes = ValidNodeTypes.Get();
Expand All @@ -67,22 +69,41 @@ private CompareResult Compare(
{
var lowerCaseName =
syntaxNodeType.Name[0].ToString().ToLower() + syntaxNodeType.Name[1..];
sourceBuilder.AppendLine(
$@" case {syntaxNodeType.Name} {lowerCaseName}:
return this.Compare{syntaxNodeType.Name}({lowerCaseName}, formattedNode as {syntaxNodeType.Name});"
);

if (syntaxNodeType == typeof(UsingDirectiveSyntax))
{
sourceBuilder.AppendLine(
$"""
case {syntaxNodeType.Name} {lowerCaseName}:
if (this.IgnoreDisabledText)
return Equal;
return this.Compare{syntaxNodeType.Name}({lowerCaseName}, formattedNode as {syntaxNodeType.Name});
"""
);
}
else
{
sourceBuilder.AppendLine(
$"""
case {syntaxNodeType.Name} {lowerCaseName}:
return this.Compare{syntaxNodeType.Name}({lowerCaseName}, formattedNode as {syntaxNodeType.Name});
"""
);
}
}

sourceBuilder.AppendLine(
@" default:
"""
default:
#if DEBUG
throw new Exception(""Can't handle "" + originalNode.GetType().Name);
throw new Exception("Can't handle " + originalNode.GetType().Name);
#else
return Equal;
#endif
}
}
"
"""
);

foreach (var syntaxNodeType in syntaxNodeTypes)
Expand All @@ -101,9 +122,11 @@ private CompareResult Compare(
private static void GenerateMethod(StringBuilder sourceBuilder, Type type)
{
sourceBuilder.AppendLine(
@$" private CompareResult Compare{type.Name}({type.Name} originalNode, {type.Name} formattedNode)
{{
CompareResult result;"
$$"""
private CompareResult Compare{{type.Name}}({{type.Name}} originalNode, {{type.Name}} formattedNode)
{
CompareResult result;
"""
);

foreach (var propertyInfo in type.GetProperties().OrderBy(o => o.Name))
Expand Down
2 changes: 1 addition & 1 deletion Src/CSharpier.FakeGenerators/ValidNodeTypes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace CSharpier.FakeGenerators;

public static class ValidNodeTypes
{
public static IEnumerable<Type> Get()
public static IList<Type> Get()
{
return typeof(CompilationUnitSyntax).Assembly
.GetTypes()
Expand Down
7 changes: 6 additions & 1 deletion Src/CSharpier.Playground/ClientApp/src/AppContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,12 @@ export const useSetupAppContext = () => {
formatCode: async () => {
setIsLoading(true);

const { syntaxTree, formattedCode, doc, hasErrors } = await formatCode(enteredCode);
const { syntaxTree, formattedCode, doc, hasErrors, syntaxValidation } = await formatCode(enteredCode);

if (syntaxValidation) {
console.log(syntaxValidation);
console.log(new Date());
}

setIsLoading(false);
setSyntaxTree(syntaxTree);
Expand Down
1 change: 1 addition & 0 deletions Src/CSharpier.Playground/ClientApp/src/FormatCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const formatCode = async (code: string) => {
formattedCode: data.code,
doc: data.doc,
hasErrors: !!data.errors.length,
syntaxValidation: data.syntaxValidation
};
} else {
const text = await response.text();
Expand Down
10 changes: 10 additions & 0 deletions Src/CSharpier.Playground/Controllers/FormatController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class FormatResult
public required string Json { get; set; }
public required string Doc { get; set; }
public required List<FormatError> Errors { get; set; }
public required string SyntaxValidation { get; set; }
}

public class FormatError
Expand Down Expand Up @@ -53,12 +54,21 @@ public async Task<FormatResult> Post([FromBody] string content)
}
);

var comparer = new SyntaxNodeComparer(
content,
result.Code,
result.ReorderedModifiers,
result.ReorderedUsingsWithDisabledText,
CancellationToken.None
);

return new FormatResult
{
Code = result.Code,
Json = result.AST,
Doc = result.DocTree,
Errors = result.CompilationErrors.Select(this.ConvertError).ToList(),
SyntaxValidation = await comparer.CompareSourceAsync(CancellationToken.None)
};
}

Expand Down
1 change: 1 addition & 0 deletions Src/CSharpier.Tests/FormattingTests/BaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ protected async Task RunTest(string fileName, string fileExtension, bool useTabs
expectedCode,
normalizedCode,
false,
false,
CancellationToken.None
);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#if DEBUG
namespace Namespace;

using System.Runtime.Remoting;
using System;

class ClassName { }

#endif

1 change: 1 addition & 0 deletions Src/CSharpier.Tests/Samples/Samples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public static async Task RunTest(string fileName)
code,
result.Code,
false,
false,
CancellationToken.None
);

Expand Down
11 changes: 8 additions & 3 deletions Src/CSharpier.Tests/SyntaxNodeComparerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ public void Usings_With_Directives_Pass_Validation(string content)
{content}
";

var result = CompareSource(left, right, ignoreDisabledText: true);
var result = CompareSource(left, right, reorderedUsingsWithDisabledText: true);

result.Should().BeEmpty();
}
Expand All @@ -507,12 +507,17 @@ private static void ResultShouldBe(string result, string be)
result.Should().Be(be);
}

private static string CompareSource(string left, string right, bool ignoreDisabledText = false)
private static string CompareSource(
string left,
string right,
bool reorderedUsingsWithDisabledText = false
)
{
var result = new SyntaxNodeComparer(
left,
right,
ignoreDisabledText,
false,
reorderedUsingsWithDisabledText,
CancellationToken.None
).CompareSource();

Expand Down
9 changes: 6 additions & 3 deletions Src/CSharpier/CSharpFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ bool TryGetCompilationFailure(out CodeFormatterResult compilationResult)
var formattingContext = new FormattingContext { LineEnding = lineEnding };
var document = Node.Print(rootNode, formattingContext);
var formattedCode = DocPrinter.DocPrinter.Print(document, printerOptions, lineEnding);
var ignoreDisabledText = formattingContext.IgnoreDisabledText;
var reorderedModifiers = formattingContext.ReorderedModifiers;
var reorderedUsingsWithDisabledText = formattingContext.ReorderedUsingsWithDisabledText;

foreach (var symbolSet in PreprocessorSymbols.GetSets(syntaxTree))
{
Expand All @@ -124,7 +125,8 @@ await syntaxTree.GetRootAsync(cancellationToken),
formattingContext2
);
formattedCode = DocPrinter.DocPrinter.Print(document, printerOptions, lineEnding);
ignoreDisabledText = ignoreDisabledText || formattingContext2.IgnoreDisabledText;
reorderedModifiers = reorderedModifiers || formattingContext2.ReorderedModifiers;
reorderedUsingsWithDisabledText = reorderedUsingsWithDisabledText || formattingContext2.ReorderedUsingsWithDisabledText;
}

return new CodeFormatterResult
Expand All @@ -134,7 +136,8 @@ await syntaxTree.GetRootAsync(cancellationToken),
? DocSerializer.Serialize(document)
: string.Empty,
AST = printerOptions.IncludeAST ? PrintAST(rootNode) : string.Empty,
IgnoreDisabledText = ignoreDisabledText
ReorderedModifiers = reorderedModifiers,
ReorderedUsingsWithDisabledText = reorderedUsingsWithDisabledText,
};
}
catch (InTooDeepException)
Expand Down
3 changes: 2 additions & 1 deletion Src/CSharpier/CodeFormatterResult.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ internal CodeFormatterResult() { }

internal static readonly CodeFormatterResult Null = new();

internal bool IgnoreDisabledText { get; init; }
internal bool ReorderedModifiers { get; init; }
internal bool ReorderedUsingsWithDisabledText { get; init; }
}
21 changes: 16 additions & 5 deletions Src/CSharpier/SyntaxNodeComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ internal partial class SyntaxNodeComparer
protected string NewSourceCode { get; }
protected SyntaxTree OriginalSyntaxTree { get; }
protected SyntaxTree NewSyntaxTree { get; }
protected bool IgnoreDisabledText { get; }
protected bool ReorderedModifiers { get; }
protected bool ReorderedUsingsWithDisabledText { get; }

private static readonly CompareResult Equal = new();

public SyntaxNodeComparer(
string originalSourceCode,
string newSourceCode,
bool ignoreDisabledText,
bool reorderedModifiers,
bool reorderedUsingsWithDisabledText,
CancellationToken cancellationToken
)
{
this.OriginalSourceCode = originalSourceCode;
this.NewSourceCode = newSourceCode;
this.IgnoreDisabledText = ignoreDisabledText;
this.ReorderedModifiers = reorderedModifiers;
this.ReorderedUsingsWithDisabledText = reorderedUsingsWithDisabledText;

var cSharpParseOptions = new CSharpParseOptions(CSharpFormatter.LanguageVersion);
this.OriginalSyntaxTree = CSharpSyntaxTree.ParseText(
Expand All @@ -43,6 +46,14 @@ public string CompareSource()

public async Task<string> CompareSourceAsync(CancellationToken cancellationToken)
{
// this seems almost impossible to figure out with the current way this is written
// the usings could be in disabled text on namespaces, or on the modifiers of any base types.
// parts of the #if or #endif could be leading trivia in different places
if (this.ReorderedUsingsWithDisabledText)
{
return string.Empty;
}

var result = this.AreEqualIgnoringWhitespace(
await this.OriginalSyntaxTree.GetRootAsync(cancellationToken),
await this.NewSyntaxTree.GetRootAsync(cancellationToken)
Expand Down Expand Up @@ -199,7 +210,7 @@ private CompareResult Compare(
)
{
if (
this.IgnoreDisabledText
this.ReorderedModifiers
&& (
(
formattedNode is NamespaceDeclarationSyntax nd
Expand Down Expand Up @@ -249,7 +260,7 @@ private CompareResult Compare(SyntaxTrivia originalTrivia, SyntaxTrivia formatte
{
if (originalTrivia.RawSyntaxKind() is SyntaxKind.DisabledTextTrivia)
{
if (this.IgnoreDisabledText)
if (this.ReorderedModifiers)
{
return Equal;
}
Expand Down
2 changes: 2 additions & 0 deletions Src/CSharpier/SyntaxNodeComparer.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,8 @@ private CompareResult Compare(
case UnsafeStatementSyntax unsafeStatementSyntax:
return this.CompareUnsafeStatementSyntax(unsafeStatementSyntax, formattedNode as UnsafeStatementSyntax);
case UsingDirectiveSyntax usingDirectiveSyntax:
if (this.ReorderedModifiers)
return Equal;
return this.CompareUsingDirectiveSyntax(usingDirectiveSyntax, formattedNode as UsingDirectiveSyntax);
case UsingStatementSyntax usingStatementSyntax:
return this.CompareUsingStatementSyntax(usingStatementSyntax, formattedNode as UsingStatementSyntax);
Expand Down
7 changes: 4 additions & 3 deletions Src/CSharpier/SyntaxPrinter/FormattingContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ internal class FormattingContext

// we need to keep track if we reordered modifiers because when modifiers are moved inside
// of an #if, then we can't compare the before and after disabled text in the source file
// we also need to keep track if we move around usings, because then the disabled text may end up on
// the first node after the usings, like namespace or class declaration
public bool IgnoreDisabledText { get; set; }
public bool ReorderedModifiers { get; set; }

// we also need to keep track if we move around usings with disabledText
public bool ReorderedUsingsWithDisabledText { get; set; }
}
2 changes: 1 addition & 1 deletion Src/CSharpier/SyntaxPrinter/Modifiers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Func<IReadOnlyList<SyntaxToken>, Doc> print
&& sortedModifiers.Zip(modifiers, (original, sorted) => original != sorted).Any()
)
{
context.IgnoreDisabledText = true;
context.ReorderedModifiers = true;
}

return print(sortedModifiers.ToArray());
Expand Down
4 changes: 2 additions & 2 deletions Src/CSharpier/SyntaxPrinter/UsingDirectives.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,9 @@ var groupOfUsingData in GroupUsings(
}
}

if (reorderedDirectives)
if (reorderedDirectives && usings.Any(o => o.ToFullString().Contains("#endif")))
{
context.IgnoreDisabledText = true;
context.ReorderedUsingsWithDisabledText = true;
}

return Doc.Concat(docs);
Expand Down

0 comments on commit ebf21c6

Please sign in to comment.