Skip to content

Commit

Permalink
Support for basic if/elif directives
Browse files Browse the repository at this point in the history
closes #15
  • Loading branch information
belav committed Aug 18, 2021
1 parent 8c72621 commit b32d040
Show file tree
Hide file tree
Showing 12 changed files with 436 additions and 8 deletions.
39 changes: 39 additions & 0 deletions Src/CSharpier.Tests/CommandLineFormatterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,45 @@ public void File_With_Mismatched_Line_Endings_In_Verbatim_String_Should_Pass_Val
exitCode.Should().Be(0);
}

[Test]
public void File_Should_Format_With_Supplied_Symbols()
{
WhenAFileExists(".csharpierrc", @"{ ""preprocessorSymbolSets"": [[""FORMAT""]] }");
WhenAFileExists(
"file1.cs",
@"public class ClassName
{
#if FORMAT
public string ShortPropertyName;
#elif NO_FORMAT
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif
}
"
);

this.Format();

var result = GetFileContent("file1.cs");

result.Should()
.Be(
@"public class ClassName
{
#if FORMAT
public string ShortPropertyName;
#elif NO_FORMAT
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif
}
"
);
}

private (int exitCode, IList<string> lines) Format(
bool skipWrite = false,
bool check = false,
Expand Down
27 changes: 25 additions & 2 deletions Src/CSharpier.Tests/ConfigurationFileOptionsTests.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Collections.Generic;
using System.IO.Abstractions.TestingHelpers;
using FluentAssertions;
using NUnit.Framework;
Expand Down Expand Up @@ -36,22 +37,43 @@ public void Should_Return_Default_Options_With_No_File()
[Test]
public void Should_Return_Json_Extension_Options()
{
WhenAFileExists("c:/test/.csharpierrc.json", "{ \"printWidth\": 10 }");
WhenAFileExists(
"c:/test/.csharpierrc.json",
@"{
""printWidth"": 10,
""preprocessorSymbolSets"": [[""1"",""2""], [""3""]]
}"
);

var result = CreateConfigurationOptions("c:/test");

result.PrintWidth.Should().Be(10);
result.PreprocessorSymbolSets.Should()
.BeEquivalentTo(new List<string[]> { new[] { "1", "2" }, new[] { "3" } });
}

[TestCase("yaml")]
[TestCase("yml")]
public void Should_Return_Yaml_Extension_Options(string extension)
{
WhenAFileExists($"c:/test/.csharpierrc.{extension}", "printWidth: 10");
WhenAFileExists(
$"c:/test/.csharpierrc.{extension}",
@"
printWidth: 10
preprocessorSymbolSets:
-
- 1
- 2
-
- 3
"
);

var result = CreateConfigurationOptions("c:/test");

result.PrintWidth.Should().Be(10);
result.PreprocessorSymbolSets.Should()
.BeEquivalentTo(new List<string[]> { new[] { "1", "2" }, new[] { "3" } });
}

[TestCase("{ \"printWidth\": 10 }")]
Expand Down Expand Up @@ -115,6 +137,7 @@ public void Should_Return_PrintWidth_With_Yaml()
private void ShouldHaveDefaultOptions(ConfigurationFileOptions configurationFileOptions)
{
configurationFileOptions.PrintWidth.Should().Be(100);
configurationFileOptions.PreprocessorSymbolSets.Should().BeNull();
}

private ConfigurationFileOptions CreateConfigurationOptions(string baseDirectoryPath)
Expand Down
80 changes: 80 additions & 0 deletions Src/CSharpier.Tests/SyntaxPrinter/PreprocessorSymbolsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System;
using System.Linq;
using CSharpier.SyntaxPrinter;
using FluentAssertions;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using NUnit.Framework;

namespace CSharpier.Tests.SyntaxPrinter
{
public class PreprocessorSymbolsTests
{
[TestCase("BASIC_IF", "BASIC_IF")]
[TestCase("!NOT_IF", "NOT_IF")]
[TestCase("EQUALS_TRUE == true", "EQUALS_TRUE")]
[TestCase("EQUALS_FALSE == false", "EQUALS_FALSE")]
[TestCase("true == TRUE_EQUALS", "TRUE_EQUALS")]
[TestCase("false == FALSE_EQUALS", "FALSE_EQUALS")]
[TestCase("LEFT_OR || RIGHT_OR", "LEFT_OR")]
[TestCase("LEFT_AND && RIGHT_AND", "LEFT_AND", "RIGHT_AND")]
[TestCase("(EQUALS_TRUE_IN_PARENS == true)", "EQUALS_TRUE_IN_PARENS")]
public void AddSymbolSet_For_If(string condition, params string[] symbols)
{
var trivia = WhenIfDirectiveHasCondition(condition);

var result = AddSymbolSet(trivia);

result.Should().ContainInOrder(symbols);
}

[Test]
public void AddSymbolSet_For_Basic_Elif_Adds_Symbol()
{
var trivia = WhenElifDirectiveHasCondition("DEBUG");

var result = AddSymbolSet(trivia);

result.Should().ContainInOrder("DEBUG");
}

private string[] AddSymbolSet(ConditionalDirectiveTriviaSyntax trivia)
{
TestablePreprocessorSymbols.Reset();

TestablePreprocessorSymbols.AddSymbolSet(trivia);

return TestablePreprocessorSymbols.GetSymbolSets().FirstOrDefault()
?? Array.Empty<string>();
}

private IfDirectiveTriviaSyntax WhenIfDirectiveHasCondition(string condition)
{
return SyntaxFactory.IfDirectiveTrivia(
SyntaxFactory.ParseExpression(condition),
true,
true,
true
);
}

private ElifDirectiveTriviaSyntax WhenElifDirectiveHasCondition(string condition)
{
return SyntaxFactory.ElifDirectiveTrivia(
SyntaxFactory.ParseExpression(condition),
true,
true,
true
);
}

private class TestablePreprocessorSymbols : PreprocessorSymbols
{
public static void AddSymbolSet(
ConditionalDirectiveTriviaSyntax conditionalDirectiveTriviaSyntax
) {
AddSymbolSetForConditional(conditionalDirectiveTriviaSyntax);
}
}
}
}
3 changes: 3 additions & 0 deletions Src/CSharpier.Tests/TestFiles/BaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.IO.Abstractions;
using System.Text;
using System.Threading;
using CSharpier.SyntaxPrinter;
using DiffEngine;
using FluentAssertions;
using NUnit.Framework;
Expand Down Expand Up @@ -34,6 +35,8 @@ protected void RunTest(string folderName, string fileName, bool useTabs = false)
var fileReaderResult =
FileReader.ReadFile(filePath, new FileSystem(), CancellationToken.None).Result;

PreprocessorSymbols.Reset();

var formatter = new CodeFormatter();
var result = formatter.Format(
fileReaderResult.FileContents,
Expand Down
52 changes: 52 additions & 0 deletions Src/CSharpier.Tests/TestFiles/Directives/PreprocessorSymbols.cst
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
public class ClassName
{
#if BASIC_IF
public string ShortPropertyName;
#elif BASIC_ELIF
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if !NOT_IF
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if EQUALS_TRUE == true
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if true == TRUE_EQUALS
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if NOT_EQUALS_TRUE != true
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if true != TRUE_NOT_EQUALS
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if LEFT_AND && RIGHT_AND
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if (LEFT_PAREN && RIGHT_PAREN)
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
public class ClassName
{
#if BASIC_IF
public string ShortPropertyName;
#elif BASIC_ELIF
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if !NOT_IF
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if EQUALS_TRUE == true
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if true == TRUE_EQUALS
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if NOT_EQUALS_TRUE != true
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if true != TRUE_NOT_EQUALS
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if LEFT_AND && RIGHT_AND
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif

#if (LEFT_PAREN && RIGHT_PAREN)
public string ShortPropertyName;
#else
public string ShortPropertyName;
#endif
}
6 changes: 6 additions & 0 deletions Src/CSharpier.Tests/TestFiles/Directives/_DirectivesTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,11 @@ public void Directives()
{
this.RunTest("Directives", "Directives");
}

[Test]
public void PreprocessorSymbols()
{
this.RunTest("Directives", "PreprocessorSymbols");
}
}
}
49 changes: 44 additions & 5 deletions Src/CSharpier/CodeFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,25 @@ public async Task<CSharpierResult> FormatAsync(
PrinterOptions printerOptions,
CancellationToken cancellationToken
) {
var syntaxTree = CSharpSyntaxTree.ParseText(
code,
new CSharpParseOptions(LanguageVersion.CSharp9, DocumentationMode.Diagnose),
cancellationToken: cancellationToken
);
SyntaxTree ParseText(string codeToFormat, params string[] preprocessorSymbols)
{
return CSharpSyntaxTree.ParseText(
codeToFormat,
new CSharpParseOptions(
LanguageVersion.CSharp9,
DocumentationMode.Diagnose,
preprocessorSymbols: preprocessorSymbols
),
cancellationToken: cancellationToken
);
}

// if a user supplied symbolSets, then we should start with the first one
var initialSymbolSet = printerOptions.PreprocessorSymbolSets is { Count: > 0 }
? printerOptions.PreprocessorSymbolSets.First()
: Array.Empty<string>();

var syntaxTree = ParseText(code, initialSymbolSet);
var syntaxNode = await syntaxTree.GetRootAsync(cancellationToken);
if (syntaxNode is not CompilationUnitSyntax rootNode)
{
Expand Down Expand Up @@ -57,13 +71,38 @@ CancellationToken cancellationToken

try
{
if (printerOptions.PreprocessorSymbolSets is { Count: > 0 })
{
PreprocessorSymbols.StopCollecting();
PreprocessorSymbols.SetSymbolSets(
// we already formatted with the first set above
printerOptions.PreprocessorSymbolSets.Skip(1).ToList()
);
}

// TODO syntax validation failing??
// also the count is way off
var document = Node.Print(rootNode);
var lineEnding = GetLineEnding(code, printerOptions);
var formattedCode = DocPrinter.DocPrinter.Print(
document,
printerOptions,
lineEnding
);

PreprocessorSymbols.StopCollecting();
foreach (var symbolSet in PreprocessorSymbols.GetSymbolSets())
{
syntaxTree = ParseText(formattedCode, symbolSet);

document = Node.Print(await syntaxTree.GetRootAsync(cancellationToken));
formattedCode = DocPrinter.DocPrinter.Print(
document,
printerOptions,
lineEnding
);
}

return new CSharpierResult
{
Code = formattedCode,
Expand Down
Loading

0 comments on commit b32d040

Please sign in to comment.