Skip to content

Commit

Permalink
Add editorconfig formatter that can sort values
Browse files Browse the repository at this point in the history
  • Loading branch information
FrediKats committed May 16, 2024
1 parent df3611f commit f5eb2aa
Show file tree
Hide file tree
Showing 2 changed files with 158 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Kysect.CommonLib.Collections.Extensions;
using Kysect.Configuin.EditorConfig.DocumentModel;
using Kysect.Configuin.EditorConfig.DocumentModel.Nodes;
using Kysect.Configuin.EditorConfig.Settings;
using Kysect.Configuin.RoslynModels;

namespace Kysect.Configuin.EditorConfig.Formatter;

public class EditorConfigFormatter
{
private readonly DotnetConfigSettingsParser _settingsParser;

public EditorConfigFormatter(DotnetConfigSettingsParser settingsParser)
{
_settingsParser = settingsParser;
}

public EditorConfigDocument Format(EditorConfigDocument value)
{
List<EditorConfigPropertyNode> nodesForRemoving = new List<EditorConfigPropertyNode>();
IReadOnlyCollection<EditorConfigPropertyNode> styleRuleNodesForMoving = SelectIdeNodes(value, RoslynRuleType.StyleRule);
IReadOnlyCollection<EditorConfigPropertyNode> qualityRuleNodesForMoving = SelectIdeNodes(value, RoslynRuleType.QualityRule);
nodesForRemoving.AddRange(styleRuleNodesForMoving);
nodesForRemoving.AddRange(qualityRuleNodesForMoving);

if (nodesForRemoving.IsEmpty())
return value;

value = value.RemoveNodes(nodesForRemoving);
var autoGeneratedSection = new EditorConfigCategoryNode("*.cs", [], ["# Autoformatted values"], null);

if (styleRuleNodesForMoving.Any())
{
var styleRuleSection = new EditorConfigDocumentSectionNode("### IDE ###");

styleRuleNodesForMoving = styleRuleNodesForMoving.OrderBy(r => r.Key.Value).ToList();
foreach (EditorConfigPropertyNode styleRule in styleRuleNodesForMoving)
styleRuleSection = styleRuleSection.AddChild(styleRule);

autoGeneratedSection = autoGeneratedSection.AddChild(styleRuleSection);
}

if (qualityRuleNodesForMoving.Any())
{
var qualitySection = new EditorConfigDocumentSectionNode("### CA ###");

qualityRuleNodesForMoving = qualityRuleNodesForMoving.OrderBy(r => r.Key.Value).ToList();
foreach (EditorConfigPropertyNode qualityRule in qualityRuleNodesForMoving)
qualitySection = qualitySection.AddChild(qualityRule);

autoGeneratedSection = autoGeneratedSection.AddChild(qualitySection);
}

value = value.AddChild(autoGeneratedSection);

return value;
}

public IReadOnlyCollection<EditorConfigPropertyNode> SelectIdeNodes(EditorConfigDocument document, RoslynRuleType roslynRuleType)
{
List<EditorConfigPropertyNode> propertyNodes = document
.DescendantNodes()
.OfType<EditorConfigPropertyNode>()
.ToList();

List<EditorConfigPropertyNode> styleRuleNodes = new List<EditorConfigPropertyNode>();
foreach (EditorConfigPropertyNode editorConfigPropertyNode in propertyNodes)
{
IEditorConfigSetting editorConfigSetting = _settingsParser.ParseSetting(editorConfigPropertyNode);
if (editorConfigSetting is not RoslynSeverityEditorConfigSetting severityConfigSetting)
continue;

if (severityConfigSetting.RuleId.Type == roslynRuleType)
styleRuleNodes.Add(editorConfigPropertyNode);
}

return styleRuleNodes;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
using Kysect.Configuin.EditorConfig;
using Kysect.Configuin.EditorConfig.DocumentModel;
using Kysect.Configuin.EditorConfig.DocumentModel.Nodes;
using Kysect.Configuin.EditorConfig.Formatter;
using Kysect.Configuin.Tests.Tools;

namespace Kysect.Configuin.Tests.EditorConfig;

public class EditorConfigFormatterTests
{
private readonly EditorConfigFormatter _formatter;
private readonly EditorConfigDocumentParser _parser;

public EditorConfigFormatterTests()
{
_formatter = new EditorConfigFormatter(new DotnetConfigSettingsParser(TestLogger.ProviderForTests()));
_parser = new EditorConfigDocumentParser();
}

[Fact]
public void Format_OrderedIdeRulesWithoutHeader_HeaderAdded()
{
var input = """
first = value
dotnet_diagnostic.IDE0081.severity = none
dotnet_diagnostic.IDE0080.severity = none
dotnet_diagnostic.IDE0082.severity = warning
second = value
""";

var expected = """
first = value
second = value
# Autoformatted values
[*.cs]
### IDE ###
dotnet_diagnostic.IDE0080.severity = none
dotnet_diagnostic.IDE0081.severity = none
dotnet_diagnostic.IDE0082.severity = warning
""";

FormatAndCompare(input, expected);
}

[Fact]
public void Format_QualityAndStyleRulesMashed_ReturnOrderedLinesWithHeader()
{
var input = """
first = value
dotnet_diagnostic.IDE0081.severity = none
dotnet_diagnostic.CA2001.severity = none
second = value
dotnet_diagnostic.IDE0080.severity = none
dotnet_diagnostic.CA2000.severity = warning
""";

var expected = """
first = value
second = value
# Autoformatted values
[*.cs]
### IDE ###
dotnet_diagnostic.IDE0080.severity = none
dotnet_diagnostic.IDE0081.severity = none
### CA ###
dotnet_diagnostic.CA2000.severity = warning
dotnet_diagnostic.CA2001.severity = none
""";

FormatAndCompare(input, expected);
}

private void FormatAndCompare(string input, string expected)
{
EditorConfigDocument editorConfigDocument = _parser.Parse(input);
EditorConfigDocument formattedDocument = _formatter.Format(editorConfigDocument);
formattedDocument.ToFullString().Should().Be(expected);
}
}

0 comments on commit f5eb2aa

Please sign in to comment.