Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .github/ISSUE_TEMPLATE/bug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ body:
Thanks for taking the time to report a bug! Please fill out the information below to help us investigate.

**Before submitting**, please check:
- I've searched [existing issues](https://github.com/belav/csharpier/issues) to ensure this isn't a duplicate
- I've read the [documentation](https://csharpier.com/) and this isn't expected behavior
- I'm using the latest version of CSharpier ![CSharpier](https://img.shields.io/nuget/v/CSharpier)
- I'm using the latest version of CSharpier's IDE plugin and understand it is versioned independently of CSharpier
- [ ] I've searched [existing issues](https://github.com/belav/csharpier/issues) to ensure this isn't a duplicate
- [ ] I've read the [documentation](https://csharpier.com/) and this isn't expected behavior
- [ ] For formatting issues I have recreated the issue on the [playground](https://playground.csharpier.com/)
- [ ] I'm using the latest version of CSharpier `1.2.5`
- [ ] I'm using the latest version of my IDE's CSharpier plugin `>= 10.0.0`


- type: textarea
id: description
Expand Down
8 changes: 8 additions & 0 deletions .github/workflows/ValidatePullRequest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ jobs:
rm -r -f ./Tests/CSharpier.MsBuild.Test
dotnet tool restore
dotnet csharpier check .
cd ./Src/CSharpier.Rider
npm install
npm run prettier:check
cd ..
cd ./CSharpier.Playground/ClientApp
npm install
npm run prettier:check

check_todos:
runs-on: ubuntu-latest
name: Check TODOs
Expand Down
5 changes: 5 additions & 0 deletions Shell/Release.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ function CSH-Release {

Set-Content -Encoding UTF8 -Path $changeLogPath -Value ($changeLog + $changeLogValue)

$bugFilePath = $PSScriptRoot + "/../.github/ISSUE_TEMPLATE/bug.yml"
$replacementText = "- [ ] I'm using the latest version of CSharpier ``$versionNumber``"
(Get-Content $bugFilePath) -replace '- \[ \] I''m using the latest version of CSharpier `\d+(\.\d+)*`', $replacementText |
Set-Content -Encoding UTF8 $bugFilePath

foreach ($file in Get-ChildItem ($PSScriptRoot + "/../docs") -Filter "*.md")
{
Copy-Item $file.FullName ($PSScriptRoot + "/../Src/Website/docs/" + $file.Name)
Expand Down
5 changes: 4 additions & 1 deletion Src/CSharpier.Cli/CommandLineFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,10 @@ CancellationToken cancellationToken
{
IFormattingValidator? formattingValidator = null;

if (printerOptions.Formatter is Formatter.CSharp or Formatter.CSharpScript)
if (
printerOptions.Formatter is Formatter.CSharp or Formatter.CSharpScript
&& fileToFormatInfo.FileContents != codeFormattingResult.Code
)
{
var sourceCodeKind =
printerOptions.Formatter is Formatter.CSharpScript
Expand Down
24 changes: 22 additions & 2 deletions Src/CSharpier.Cli/EditorConfig/EditorConfigSections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ internal class EditorConfigSections
printerOptions.EndOfLine = endOfLine;
}

if (resolvedConfiguration.XmlWhitespaceSensitivity is { } xmlWhitespaceSensitivity)
{
printerOptions.XmlWhitespaceSensitivity = xmlWhitespaceSensitivity;
}

return printerOptions;
}

Expand All @@ -63,6 +68,7 @@ private class ResolvedConfiguration
public int? TabWidth { get; }
public int? MaxLineLength { get; }
public EndOfLine? EndOfLine { get; }
public XmlWhitespaceSensitivity? XmlWhitespaceSensitivity { get; set; }
public string? Formatter { get; }

public ResolvedConfiguration(List<Section> sections)
Expand Down Expand Up @@ -104,9 +110,23 @@ public ResolvedConfiguration(List<Section> sections)
}

var endOfLine = sections.LastOrDefault(o => o.EndOfLine != null)?.EndOfLine;
if (Enum.TryParse(endOfLine, true, out EndOfLine result))
if (Enum.TryParse(endOfLine, true, out EndOfLine parsedEndOfLine))
{
this.EndOfLine = parsedEndOfLine;
}

var xmlWhitespaceSensitivity = sections
.LastOrDefault(o => o.XmlWhitespaceSensitivity != null)
?.XmlWhitespaceSensitivity;
if (
Enum.TryParse(
xmlWhitespaceSensitivity,
true,
out XmlWhitespaceSensitivity parsedXmlWhitespaceSensitivity
)
)
{
this.EndOfLine = result;
this.XmlWhitespaceSensitivity = parsedXmlWhitespaceSensitivity;
}

this.Formatter = sections.LastOrDefault(o => o.Formatter is not null)?.Formatter;
Expand Down
2 changes: 2 additions & 0 deletions Src/CSharpier.Cli/EditorConfig/Section.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ internal class Section(SectionData section, string directory)
public string? MaxLineLength { get; } = section.Keys["max_line_length"];
public string? EndOfLine { get; } = section.Keys["end_of_line"];
public string? Formatter { get; } = section.Keys["csharpier_formatter"];
public string? XmlWhitespaceSensitivity { get; } =
section.Keys["csharpier_xml_whitespace_sensitivity"];

public bool IsMatch(string fileName, bool ignoreDirectory)
{
Expand Down
15 changes: 13 additions & 2 deletions Src/CSharpier.Cli/IgnoreFile.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Concurrent;
using System.IO.Abstractions;
using CSharpier.Cli.DotIgnore;
using CSharpier.Core;
Expand Down Expand Up @@ -35,17 +36,27 @@ public bool IsIgnored(string filePath)
string baseDirectoryPath,
IFileSystem fileSystem,
string? ignorePath,
ConcurrentDictionary<string, IgnoreList>? ignoreCache,
CancellationToken cancellationToken
)
{
Task<IgnoreList> CreateIgnore(string ignoreFilePath, string? overrideBasePath)
async Task<IgnoreList> CreateIgnore(string ignoreFilePath, string? overrideBasePath)
{
return IgnoreList.CreateAsync(
if (ignoreCache is not null && ignoreCache.TryGetValue(ignoreFilePath, out var ignore))
{
return ignore;
}

ignore = await IgnoreList.CreateAsync(
fileSystem,
overrideBasePath ?? Path.GetDirectoryName(ignoreFilePath)!,
ignoreFilePath,
cancellationToken
);

ignoreCache?[ignoreFilePath] = ignore;

return ignore;
}

return await SharedFunc<IgnoreFile?>
Expand Down
10 changes: 10 additions & 0 deletions Src/CSharpier.Cli/Options/ConfigurationFileOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ internal class ConfigurationFileOptions
public int? IndentSize { get; init; }
public bool UseTabs { get; init; }

[JsonConverter(typeof(CaseInsensitiveEnumConverter<XmlWhitespaceSensitivity>))]
public XmlWhitespaceSensitivity XmlWhitespaceSensitivity { get; init; } =
XmlWhitespaceSensitivity.Strict;

[JsonConverter(typeof(CaseInsensitiveEnumConverter<EndOfLine>))]
public EndOfLine EndOfLine { get; init; }

Expand Down Expand Up @@ -38,6 +42,7 @@ out var parsedFormatter
UseTabs = matchingOverride.UseTabs,
Width = matchingOverride.PrintWidth,
EndOfLine = matchingOverride.EndOfLine,
XmlWhitespaceSensitivity = matchingOverride.XmlWhitespaceSensitivity,
};
}

Expand All @@ -50,6 +55,7 @@ out var parsedFormatter
UseTabs = this.UseTabs,
Width = this.PrintWidth,
EndOfLine = this.EndOfLine,
XmlWhitespaceSensitivity = this.XmlWhitespaceSensitivity,
};
}

Expand All @@ -73,6 +79,10 @@ internal class Override
public int IndentSize { get; init; } = 4;
public bool UseTabs { get; init; }

[JsonConverter(typeof(CaseInsensitiveEnumConverter<XmlWhitespaceSensitivity>))]
public XmlWhitespaceSensitivity XmlWhitespaceSensitivity { get; init; } =
XmlWhitespaceSensitivity.Strict;

[JsonConverter(typeof(CaseInsensitiveEnumConverter<EndOfLine>))]
public EndOfLine EndOfLine { get; init; }

Expand Down
11 changes: 10 additions & 1 deletion Src/CSharpier.Cli/Options/OptionsProvider.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System.Collections.Concurrent;
using System.IO.Abstractions;
using System.Text.Json;
using CSharpier.Cli.DotIgnore;
using CSharpier.Cli.EditorConfig;
using CSharpier.Core;
using Microsoft.Extensions.Logging;
Expand All @@ -15,6 +16,7 @@ private readonly ConcurrentDictionary<
string,
CSharpierConfigData?
> csharpierConfigsByDirectory = new();
private readonly ConcurrentDictionary<string, IgnoreList> ignoreWithPathCache = new();
private readonly ConcurrentDictionary<string, IgnoreFile?> ignoreFilesByDirectory = new();
private readonly ConfigurationFileOptions? specifiedConfigFile;
private readonly EditorConfigSections? specifiedEditorConfig;
Expand Down Expand Up @@ -60,6 +62,7 @@ CancellationToken cancellationToken
directoryName,
fileSystem,
ignorePath,
null,
cancellationToken
);

Expand Down Expand Up @@ -204,7 +207,13 @@ CancellationToken cancellationToken
Path.Combine(searchingDirectory, ".csharpierignore")
),
(searchingDirectory) =>
IgnoreFile.CreateAsync(searchingDirectory, this.fileSystem, null, cancellationToken)
IgnoreFile.CreateAsync(
searchingDirectory,
this.fileSystem,
null,
ignoreWithPathCache,
cancellationToken
)
);

#pragma warning disable IDE0270
Expand Down
92 changes: 77 additions & 15 deletions Src/CSharpier.Core/CSharp/SyntaxNodeComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ CancellationToken cancellationToken
cSharpParseOptions,
cancellationToken: cancellationToken
);
this.CompareFunc = Compare;
}

public string CompareSource()
Expand Down Expand Up @@ -148,14 +149,16 @@ SyntaxNode formattedStart
return Equal;
}

#pragma warning disable CA1822
private CompareResult CompareLists<T>(
IReadOnlyList<T> originalList,
IReadOnlyList<T> formattedList,
Func<T, T, CompareResult> comparer,
Func<T, TextSpan> getSpan,
T originalList,
T formattedList,
Func<SyntaxToken, SyntaxToken, CompareResult> comparer,
Func<SyntaxToken, TextSpan> getSpan,
TextSpan originalParentSpan,
TextSpan newParentSpan
)
where T : IReadOnlyList<SyntaxToken>
{
for (var x = 0; x < originalList.Count || x < formattedList.Count; x++)
{
Expand All @@ -169,25 +172,71 @@ TextSpan newParentSpan
return NotEqual(getSpan(originalList[x]), newParentSpan);
}

if (
originalList[x] is SyntaxNode originalNode
&& formattedList[x] is SyntaxNode formattedNode
)
var result = comparer(originalList[x], formattedList[x]);
if (result.IsInvalid)
{
return result;
}
}

return Equal;
}
#pragma warning restore CA1822

private CompareResult CompareLists<T>(
T originalList,
T formattedList,
Func<SyntaxNode, SyntaxNode, CompareResult> comparer,
Func<SyntaxNode, TextSpan> getSpan,
TextSpan originalParentSpan,
TextSpan newParentSpan
)
where T : IReadOnlyList<SyntaxNode>
{
for (var x = 0; x < originalList.Count || x < formattedList.Count; x++)
{
if (x == originalList.Count)
{
this.originalStack.Push((originalNode, originalNode.Parent));
this.formattedStack.Push((formattedNode, formattedNode.Parent));
return NotEqual(originalParentSpan, getSpan(formattedList[x]));
}
else

if (x == formattedList.Count)
{
var result = comparer(originalList[x], formattedList[x]);
if (result.IsInvalid)
return NotEqual(getSpan(originalList[x]), newParentSpan);
}

var originalNode = originalList[x];
var formattedNode = formattedList[x];
this.originalStack.Push((originalNode, originalNode.Parent));
this.formattedStack.Push((formattedNode, formattedNode.Parent));
}

return Equal;
}

private static SyntaxToken[] AllSeparatorsButLast(in SeparatedSyntaxList<SyntaxNode> list)
{
if (list.Count <= 1)
{
return [];
}

var tokens = new SyntaxToken[list.Count - 1];
var tokenIndex = 0;

foreach (var element in list.GetWithSeparators())
{
if (element.IsToken)
{
tokens[tokenIndex++] = element.AsToken();
if (tokenIndex == tokens.Length)
{
return result;
break;
}
}
}

return Equal;
return tokens;
}

private static CompareResult NotEqual(SyntaxNode? originalNode, SyntaxNode? formattedNode)
Expand All @@ -210,6 +259,8 @@ private static CompareResult NotEqual(TextSpan? originalSpan, TextSpan? formatte
};
}

private Func<SyntaxToken, SyntaxToken, CompareResult> CompareFunc { get; }

private CompareResult Compare(SyntaxToken originalToken, SyntaxToken formattedToken)
{
return this.Compare(originalToken, formattedToken, null, null);
Expand Down Expand Up @@ -322,6 +373,17 @@ private CompareResult Compare(SyntaxTrivia originalTrivia, SyntaxTrivia formatte
: NotEqual(originalTrivia.Span, formattedTrivia.Span);
}

private bool CompareFullSpan(SyntaxNode originalStart, SyntaxNode formattedStart)
{
var originalSpan = OriginalSourceCode
.AsSpan()
.Slice(originalStart.FullSpan.Start, originalStart.FullSpan.Length);
var formattedSpan = NewSourceCode
.AsSpan()
.Slice(formattedStart.FullSpan.Start, formattedStart.FullSpan.Length);
return originalSpan == formattedSpan;
}

private static CompareResult CompareComment(
string originalComment,
string formattedComment,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public static List<Doc> Print<T>(
)
where T : MemberDeclarationSyntax
{
var result = new List<Doc>();
var result = new List<Doc>(members.Count * 3);
if (!skipFirstHardLine)
{
result.Add(Doc.HardLine);
Expand Down
1 change: 1 addition & 0 deletions Src/CSharpier.Core/CSharp/SyntaxPrinter/Modifiers.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CSharpier.Core.DocTypes;
using CSharpier.Core.Utilities;
using Microsoft.CodeAnalysis;

namespace CSharpier.Core.CSharp.SyntaxPrinter;
Expand Down
1 change: 1 addition & 0 deletions Src/CSharpier.Core/CSharp/SyntaxPrinter/RightHandSide.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using CSharpier.Core.DocTypes;
using CSharpier.Core.Utilities;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ internal static class Argument
{
public static Doc Print(ArgumentSyntax node, PrintingContext context)
{
return Doc.Concat(PrintModifiers(node, context), Node.Print(node.Expression, context));
var modifiers = PrintModifiers(node, context);

return modifiers == Doc.Null
? Node.Print(node.Expression, context)
: Doc.Concat(modifiers, Node.Print(node.Expression, context));
}

public static Doc PrintModifiers(ArgumentSyntax node, PrintingContext context)
Expand Down
Loading