Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing rules for when lines are forced before members #535

Merged
merged 15 commits into from
Jan 3, 2022
1 change: 1 addition & 0 deletions CSharpier.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
<s:Boolean x:Key="/Default/UserDictionary/Words/=Concated/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=csharpierignore/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=csharpierrc/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=externs/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Sharpier/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
68 changes: 42 additions & 26 deletions Src/CSharpier.Playground/ClientApp/src/FormatCode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,53 @@ let marks: any[] = [];
let editor: any = undefined;

export const formatCode = async (code: string) => {
const response = await fetch("/Format", {
method: "POST",
body: JSON.stringify(code),
headers: {
"Content-Type": "application/json",
"cache-control": "no-cache",
},
});
if (response.status === 200) {
const data = await response.json();
const makeRequest = async () => {
const response = await fetch("/Format", {
method: "POST",
body: JSON.stringify(code),
headers: {
"Content-Type": "application/json",
"cache-control": "no-cache",
},
});
if (response.status === 200) {
const data = await response.json();

setTimeout(() => {
setupMarks(data.errors);
}, 100);
setTimeout(() => {
setupMarks(data.errors);
}, 100);

return {
syntaxTree: JSON.parse(data.json),
formattedCode: data.code,
doc: data.doc,
hasErrors: !!data.errors.length,
};
} else {
const text = await response.text();
return {
formattedCode: text,
doc: text,
hasErrors: true,
};
return {
syntaxTree: JSON.parse(data.json),
formattedCode: data.code,
doc: data.doc,
hasErrors: !!data.errors.length,
};
} else {
const text = await response.text();
return {
formattedCode: text,
doc: text,
hasErrors: true,
};
}
}

for (let x = 0; x < 5; x++) {
try {
return makeRequest();
}
catch {
await sleep(500);
}
}
return makeRequest();
};

function sleep (milliseconds: number) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}

const setupMarks = (errors: any[]) => {
if (!editor) {
setTimeout(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
[assembly: System.Copyright("(C) 2009")]
[module: System.Copyright("\n\t\u0123(C) \"2009" + "\u0123")]

[Obsolete]
class ClassName
{
[Obsolete]
private string Field;

[Obsolete]
public string Property
{
Expand Down
2 changes: 2 additions & 0 deletions Src/CSharpier.Tests/FormattingTests/TestFiles/Comments.cst
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@ public class ClassName
}

IReadOnlyList<IArgument> ICommand.Arguments => Arguments;

/// <DocumentationCommentDoesNotCauseBreaking />
IReadOnlyList<IArgument> ICommand.Arguments => Arguments;

// regular comment does not cause breaking
IReadOnlyList<IArgument> ICommand.Arguments => Arguments;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
using System.Diagnostics.CodeAnalysis;
[assembly: ForceLineAbove]
[assembly: ButNotHere]

[assembly: ButKeepThisOne]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System.Diagnostics.CodeAnalysis;

[assembly: ForceLineAbove]
[assembly: ButNotHere]

[assembly: ButKeepThisOne]
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Diagnostics.Contracts;
using System.Linq;
using System.Reflection;

#if KEEP_LINE_ABOVE
namespace System.Web.Http.Internal
#else
namespace System.Web.WebPages
#endif
{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#if DONT_ADD_EXTRA_LINES
using System.Net.Http;
#else
using System.Web.Routing;
#endif

#if DONT_ADD_EXTRA_LINES
namespace System.Web.Http.Routing.Constraints
#else
namespace System.Web.Mvc.Routing.Constraints
#endif
{ }
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#if NO_DOUBLE_LINE_WITH_FILE_SCOPED
using System;

#endif

namespace Namespace;
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System.Runtime.CompilerServices;
#if NO_EXTRA_LINES_WITH_ATTRIBUTE
using System.Runtime.CompilerServices;
#endif

[assembly: Attribute]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using System.Runtime.CompilerServices;

#if KEEP_LINE_ABOVE
[assembly: Attribute]
#endif
[assembly: Attribute]
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#if NO_EXTRA_LINES
extern alias Foo1;
#else
extern alias Foo2;
#endif

#if NO_EXTRA_LINES
using System.Net.Http;
#else
using System.Web.Routing;
#endif

using System.Web.Http;

#if KEEP_LINE_ABOVE
using System.Web.Http;
#endif

namespace Namespace { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace FileScoped;

#if NO_EXTRA_LINES
extern alias Foo1;
#else
extern alias Foo2;
#endif

#if NO_EXTRA_LINES
using System.Net.Http;
#else
using System.Web.Routing;
#endif

class ClassName { }
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
namespace Namespace
{
#if NO_EXTRA_LINES
extern alias Foo1;
#else
extern alias Foo2;
#endif

#if NO_EXTRA_LINES
using System.Net.Http;
#else
using System.Web.Routing;
#endif

class ClassName { }
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ alias // alias trailing
Foo;

extern alias Foo;

namespace Namespace
{
extern alias Bar;
Expand Down
136 changes: 136 additions & 0 deletions Src/CSharpier.Tests/FormattingTests/TestFiles/MemberLines.cst
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
public class ClassRules
{
public void NeverLineBeforeFirstMember() { }
public void AlwaysLineBetweenMethods() { }
public void EvenWithLambdaBody() => "";
private enum AlwaysLineBeforeEnum
{
One,
Two
}

private enum NoDoubleLines
{
One,
Two
}
private class AlwaysLineBeforeClass { }

private class NoDoubleLines { }
private interface IAlwaysLineBeforeInterface { }

private interface INoDoubleLines { }
public ClassRules() { }

public ClassRules() { }
public ~ClassName() { }

public ~ClassName() { }
public static implicit operator ClassRules(string s)
{
return new Test();
}

public static implicit operator ClassRules(int i)
{
return new Test();
}
public record SomeRecord1(string property);

public record SomeRecord2(string property);
public struct SomeStruct1 { }

public struct SomeStruct2 { }
static ClassRules operator +(ClassRules a, ClassRules b)
{
return a.Add(b);
}

static ClassRules operator -(ClassRules a, ClassRules b)
{
return a.Subtract(b);
}

private string FieldsCanBeGroupedBecauseLinesWillBeKept;
private string ButLinesAreNotForcedHere;
// comments force a line
private string FieldWithComment;
/* comments force a line */
private string FieldWithComment;
/// <summary> comments force a line </summary> ///
private string FieldWithComment;
[AttributesForceALine]
private string FieldWithAttribute;

private string PropertiesCanBeGrouped { get; set; }
private string BecauseTheyDontForceLines { get; set; }
// comments force a line
private string PropertyWithComment;
[AttributesForceALine]
private string PropertyWithAttribute;

delegate void DelegatesAreLikeFields();
delegate void AndCanBeGrouped();
// comments force a line
delegate void DelegateWithComment();
[AttributesForceALine]
delegate void DelegateWithAttribute();

public void AlwaysLineBetweenMethods() { }
private string FieldAfterMethodGetsLine;

#if EDGE_CASE_SHOULD_KEEP_LINE_ABOVE_METHOD
private string Field;
#else
private string Field;
#endif

public void SomeMethod() { }

#pragma warning disable 0618
public void KeepLineAboveAndBelow() { }
#pragma warning restore 0618

public void SomeMethod() { }
}
public class LineBeforeClass { }
public interface InterfaceRulesAreLikeClassesButMethodsFollowTheFieldRulesAbove
{
void NeverLineHere();

void ExistingLineHereIsKept();
void ButNoLineIsAdded();
// comments do force a line
void MethodWithComment();
}

abstract class AbstractClass
{
abstract void NoLineHere() { }

abstract void KeepTheLineHere();
abstract void DoNotForceTheLineHere();
void ButForceLineForRealMethod() { }
}

public class ClassName
{
private string someField1;

#if KEEP_LINE_ABOVE
private string someField2;
#endif

private string someField2;
}

public class ClassName
{
#region RegionWithSpaceBeforeAndAfterMethod

void SomeMethod() { }

#endregion

void SomeMethod() { }
}
Loading