Skip to content

Commit

Permalink
Actually format csx files (#1151)
Browse files Browse the repository at this point in the history
closes #1141
  • Loading branch information
belav authored Jan 28, 2024
1 parent 39b8497 commit aa3245b
Show file tree
Hide file tree
Showing 15 changed files with 114 additions and 31 deletions.
3 changes: 3 additions & 0 deletions Src/CSharpier.Benchmarks/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

namespace CSharpier.Benchmarks;

using Microsoft.CodeAnalysis;

[MemoryDiagnoser]
public class Benchmarks
{
Expand All @@ -22,6 +24,7 @@ public void Default_SyntaxNodeComparer()
this.code,
false,
false,
SourceCodeKind.Regular,
CancellationToken.None
);
syntaxNodeComparer.CompareSource();
Expand Down
9 changes: 8 additions & 1 deletion Src/CSharpier.Cli/CommandLineFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@

namespace CSharpier.Cli;

using Microsoft.CodeAnalysis;

internal static class CommandLineFormatter
{
public static async Task<int> Format(
Expand Down Expand Up @@ -375,12 +377,16 @@ CancellationToken cancellationToken

CodeFormatterResult codeFormattingResult;

var sourceCodeKind = Path.GetExtension(fileToFormatInfo.Path).EqualsIgnoreCase(".csx")
? SourceCodeKind.Script
: SourceCodeKind.Regular;

try
{
// TODO xml find correct formatter
codeFormattingResult = await CSharpFormatter.FormatAsync(
fileToFormatInfo.FileContents,
printerOptions,
sourceCodeKind,
cancellationToken
);
}
Expand Down Expand Up @@ -430,6 +436,7 @@ CancellationToken cancellationToken
codeFormattingResult.Code,
codeFormattingResult.ReorderedModifiers,
codeFormattingResult.ReorderedUsingsWithDisabledText,
sourceCodeKind,
cancellationToken
);

Expand Down
6 changes: 6 additions & 0 deletions Src/CSharpier.Playground/ClientApp/src/AppContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ export const AppContext = React.createContext({
setIndentSize: (value: number) => {},
useTabs: false,
setUseTabs: (value: boolean) => {},
parser: "CSharp",
setParser: (value: string) => {},
showAst: false,
setShowAst: (value: boolean) => {},
showDoc: false,
Expand Down Expand Up @@ -41,6 +43,7 @@ export const useSetupAppContext = () => {
const [printWidth, setPrintWidth] = useState(100);
const [indentSize, setIndentSize] = useState(4);
const [useTabs, setUseTabs] = useState(false);
const [parser, setParser] = useState("CSharp");
const [showAst, setShowAst] = useState(getInitialShowAst());
const [showDoc, setShowDoc] = useState(getInitialShowDoc());
const [hideNull, setHideNull] = useState(getInitialHideNull());
Expand All @@ -58,6 +61,8 @@ export const useSetupAppContext = () => {
setIndentSize,
useTabs,
setUseTabs,
parser,
setParser,
showAst,
setShowAst: (value: boolean) => {
window.sessionStorage.setItem("showAst", value.toString());
Expand Down Expand Up @@ -95,6 +100,7 @@ export const useSetupAppContext = () => {
printWidth,
indentSize,
useTabs,
parser,
);

if (syntaxValidation) {
Expand Down
7 changes: 7 additions & 0 deletions Src/CSharpier.Playground/ClientApp/src/Controls.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export const Controls = () => {
setIndentSize,
useTabs,
setUseTabs,
parser,
setParser,
} = useAppContext();
return (
<div className="controlsWrapper">
Expand All @@ -38,6 +40,11 @@ export const Controls = () => {
/>
Use Tabs
</label>
<label>Parser</label>
<select value={parser} onChange={e => setParser(e.target.value)}>
<option value="CSharp">C#</option>
<option value="CSharpScript">C# Script</option>
</select>
</div>
<div>
<h3>Debug</h3>
Expand Down
4 changes: 2 additions & 2 deletions Src/CSharpier.Playground/ClientApp/src/FormatCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ let gutters: any[] = [];
let marks: any[] = [];
let editor: any = undefined;

export const formatCode = async (code: string, printWidth: number, indentSize: number, useTabs: boolean) => {
export const formatCode = async (code: string, printWidth: number, indentSize: number, useTabs: boolean, parser: string) => {
const makeRequest = async () => {
const response = await fetch("/Format", {
method: "POST",
body: JSON.stringify({ code, printWidth, indentSize, useTabs }),
body: JSON.stringify({ code, printWidth, indentSize, useTabs, parser }),
headers: {
"Content-Type": "application/json",
"cache-control": "no-cache",
Expand Down
18 changes: 15 additions & 3 deletions Src/CSharpier.Playground/Controllers/FormatController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

namespace CSharpier.Playground.Controllers;

using CSharpier.Utilities;

public class FormatResult
{
public required string Code { get; set; }
Expand Down Expand Up @@ -47,11 +49,18 @@ public class PostModel
public int PrintWidth { get; set; }
public int IndentSize { get; set; }
public bool UseTabs { get; set; }
public string Parser { get; set; } = string.Empty;
}

[HttpPost]
public async Task<FormatResult> Post([FromBody] PostModel model)
public async Task<FormatResult> Post(
[FromBody] PostModel model,
CancellationToken cancellationToken
)
{
var sourceCodeKind = model.Parser.EqualsIgnoreCase("CSharp")
? SourceCodeKind.Regular
: SourceCodeKind.Script;
var result = await CSharpFormatter.FormatAsync(
model.Code,
new PrinterOptions
Expand All @@ -61,15 +70,18 @@ public async Task<FormatResult> Post([FromBody] PostModel model)
Width = model.PrintWidth,
TabWidth = model.IndentSize,
UseTabs = model.UseTabs
}
},
sourceCodeKind,
cancellationToken
);

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

return new FormatResult
Expand Down
38 changes: 34 additions & 4 deletions Src/CSharpier.Tests/CommandLineFormatterTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,19 +91,49 @@ public void Format_Writes_Unsupported()
.Be(@"Warning ./Unsupported.js - Is an unsupported file type.");
}

[TestCase(".cs")]
[TestCase(".csx")]
public void Format_Writes_File_With_Directory_Path(string extension)
public void Format_Writes_File_With_Directory_Path()
{
var context = new TestContext();
var unformattedFilePath = $"Unformatted.{extension}";
var unformattedFilePath = $"Unformatted.cs";
context.WhenAFileExists(unformattedFilePath, UnformattedClassContent);

this.Format(context);

context.GetFileContent(unformattedFilePath).Should().Be(FormattedClassContent);
}

[Test]
public void Formats_CSX_File()
{
var context = new TestContext();
var unformattedFilePath = "Unformatted.csx";
context.WhenAFileExists(
unformattedFilePath,
"""
#r "Microsoft.WindowsAzure.Storage"
public static void Run()
{
}
"""
);

var result = this.Format(context);
result.OutputLines.First().Should().StartWith("Formatted 1 files");

context
.GetFileContent(unformattedFilePath)
.Should()
.Be(
"""
#r "Microsoft.WindowsAzure.Storage"
public static void Run() { }
"""
);
}

[TestCase("0.9.0", false)]
[TestCase("9999.0.0", false)]
[TestCase("current", true)]
Expand Down
6 changes: 5 additions & 1 deletion Src/CSharpier.Tests/FormattingTests/BaseTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@

namespace CSharpier.Tests.FormattingTests;

using CSharpier.Utilities;
using Microsoft.CodeAnalysis;

public class BaseTest
{
private readonly DirectoryInfo rootDirectory = DirectoryFinder.FindParent("CSharpier.Tests");
Expand All @@ -26,10 +29,10 @@ protected async Task RunTest(string fileName, string fileExtension, bool useTabs
CancellationToken.None
);

// TODO xml use proper formatter
var result = await CSharpFormatter.FormatAsync(
fileReaderResult.FileContents,
new PrinterOptions { Width = PrinterOptions.WidthUsedByTests, UseTabs = useTabs },
fileExtension.EqualsIgnoreCase("csx") ? SourceCodeKind.Script : SourceCodeKind.Regular,
CancellationToken.None
);

Expand Down Expand Up @@ -60,6 +63,7 @@ protected async Task RunTest(string fileName, string fileExtension, bool useTabs
normalizedCode,
false,
false,
SourceCodeKind.Regular,
CancellationToken.None
);

Expand Down
5 changes: 5 additions & 0 deletions Src/CSharpier.Tests/FormattingTests/TestFiles/csx/Basics.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env dotnet-script
#r "Microsoft.WindowsAzure.Storage"
#load "mylogger.csx"

public static void Run() { }
3 changes: 3 additions & 0 deletions Src/CSharpier.Tests/Samples/Samples.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

namespace CSharpier.Tests.Samples;

using Microsoft.CodeAnalysis;

[TestFixture]
[Parallelizable(ParallelScope.All)]
public class Samples
Expand Down Expand Up @@ -41,6 +43,7 @@ public static async Task RunTest(string fileName)
result.Code,
false,
false,
SourceCodeKind.Regular,
CancellationToken.None
);

Expand Down
3 changes: 3 additions & 0 deletions Src/CSharpier.Tests/SyntaxNodeComparerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

namespace CSharpier.Tests;

using Microsoft.CodeAnalysis;

[TestFixture]
[Parallelizable(ParallelScope.All)]
public class SyntaxNodeComparerTests
Expand Down Expand Up @@ -623,6 +625,7 @@ private static string CompareSource(
right,
false,
reorderedUsingsWithDisabledText,
SourceCodeKind.Regular,
CancellationToken.None
).CompareSource();

Expand Down
19 changes: 16 additions & 3 deletions Src/CSharpier/CSharpFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ namespace CSharpier;
using CSharpier.Formatters.CSharp;
using CSharpier.SyntaxPrinter;

internal class CSharpScriptFormatter : CSharpFormatter { }

internal class CSharpFormatter : IFormatter
{
internal static readonly LanguageVersion LanguageVersion = LanguageVersion.Preview;
Expand All @@ -27,20 +29,29 @@ internal static Task<CodeFormatterResult> FormatAsync(
string code,
PrinterOptions printerOptions,
CancellationToken cancellationToken
) => FormatAsync(code, printerOptions, SourceCodeKind.Regular, cancellationToken);

internal static Task<CodeFormatterResult> FormatAsync(
string code,
PrinterOptions printerOptions,
SourceCodeKind sourceCodeKind,
CancellationToken cancellationToken
)
{
var initialSymbolSet = Array.Empty<string>();

return FormatAsync(
ParseText(code, initialSymbolSet, cancellationToken),
ParseText(code, initialSymbolSet, sourceCodeKind, cancellationToken),
printerOptions,
sourceCodeKind,
cancellationToken
);
}

private static SyntaxTree ParseText(
string codeToFormat,
IEnumerable<string> preprocessorSymbols,
SourceCodeKind sourceCodeKind,
CancellationToken cancellationToken
)
{
Expand All @@ -49,7 +60,8 @@ CancellationToken cancellationToken
new CSharpParseOptions(
LanguageVersion,
DocumentationMode.Diagnose,
preprocessorSymbols: preprocessorSymbols
preprocessorSymbols: preprocessorSymbols,
kind: sourceCodeKind
),
cancellationToken: cancellationToken
);
Expand All @@ -58,6 +70,7 @@ CancellationToken cancellationToken
internal static async Task<CodeFormatterResult> FormatAsync(
SyntaxTree syntaxTree,
PrinterOptions printerOptions,
SourceCodeKind sourceCodeKind,
CancellationToken cancellationToken
)
{
Expand Down Expand Up @@ -120,7 +133,7 @@ bool TryGetCompilationFailure(out CodeFormatterResult compilationResult)

foreach (var symbolSet in PreprocessorSymbols.GetSets(syntaxTree))
{
syntaxTree = ParseText(formattedCode, symbolSet, cancellationToken);
syntaxTree = ParseText(formattedCode, symbolSet, sourceCodeKind, cancellationToken);

if (TryGetCompilationFailure(out result))
{
Expand Down
1 change: 1 addition & 0 deletions Src/CSharpier/CodeFormatter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public static Task<CodeFormatterResult> FormatAsync(
return CSharpFormatter.FormatAsync(
syntaxTree,
new PrinterOptions { Width = options.Width },
SourceCodeKind.Regular,
cancellationToken
);
}
Expand Down
6 changes: 5 additions & 1 deletion Src/CSharpier/SyntaxNodeComparer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public SyntaxNodeComparer(
string newSourceCode,
bool reorderedModifiers,
bool reorderedUsingsWithDisabledText,
SourceCodeKind sourceCodeKind,
CancellationToken cancellationToken
)
{
Expand All @@ -26,7 +27,10 @@ CancellationToken cancellationToken
this.ReorderedModifiers = reorderedModifiers;
this.ReorderedUsingsWithDisabledText = reorderedUsingsWithDisabledText;

var cSharpParseOptions = new CSharpParseOptions(CSharpFormatter.LanguageVersion);
var cSharpParseOptions = new CSharpParseOptions(
CSharpFormatter.LanguageVersion,
kind: sourceCodeKind
);
this.OriginalSyntaxTree = CSharpSyntaxTree.ParseText(
this.OriginalSourceCode,
cSharpParseOptions,
Expand Down
Loading

0 comments on commit aa3245b

Please sign in to comment.