Bot releases are hidden (Show)
Published by belav 11 months ago
Improves error handling and reports when it is not possible to get CSharpier started to format files.
Deals with the githash in version numbers correctly.
Published by belav 11 months ago
When using CSharpier.MsBuild in a setting where the project targeted net8.0 and only the net8 sdk was installed, CSharpier.MsBuild would attempt to run the net7.0 version of csharpier and fail because the net7 sdk was not installed.
Thanks go to @aditnryn for the fix
Global using were not sorting System
to the top, which was inconsistent with regular using.
// 0.26.1
global using ZWord;
global using AWord;
global using System.Web;
global using System;
// 0.26.2
global using System;
global using System.Web;
global using AWord;
global using ZWord;
Thanks go to @vipentti for the fix
Full Changelog: https://github.com/belav/csharpier/compare/0.26.1...0.26.2
Published by belav 12 months ago
CSharpier was unable to parse an .editorconfig
file that contained duplicate sections and would crash. This would result in a hung IDE.
[*]
insert_final_newline = true
[*]
spelling_languages = en-us
Thanks go to @echoix for helping track this down.
Given the following setup
/src/.editorconfig
/src/ProjectName/.editorconfig
/src/.csharpierrc
Originally with 0.26.0, the /src/ProjectName/.editorconfig
file would be used for determining the configuration options for a file within src/ProjectName
. This resulted in the existing options within .csharpierrc
being ignored.
With 0.26.1, if a .csharpierrc
exists anywhere above a given file, it will be used to determine the configuration options.
Thanks go to @parched for reporting the issue.
Full Changelog: https://github.com/belav/csharpier/compare/0.26.0...0.26.1
Published by belav 12 months ago
CSharpier will now read configuration options from an .editorconfig
. See https://csharpier.com/docs/Configuration for more details.
CSharpier now supports the .net8 sdk. It still supports net6 and net7.
CSharpier now sorts using statements. It follows the following rules
global using System.Linq; // sort global first
using System; // sort anything in System
using NonSystem; // sort anything non-system
using static Static; // sort static
using Alias = Z; // sort alias
using SomeAlias = A;
#if DEBUG // finally any usings in #if's
using Z; // contents are not sorted as of now
using A;
#endif
// input
if (true)
CallMethod();
else if (false)
CallMethod();
else
CallMethod();
for (; ; )
CallMethod();
while (true)
CallMethod();
// 0.26.0
if (true)
CallMethod();
else if (false)
CallMethod();
else
CallMethod();
for (; ; )
CallMethod();
while (true)
CallMethod();
Thanks go to @Infinite-3D for reporting
CSharpier now supports primary constructors on structs
public struct NamedItem2(
string name1,
string name2
)
{
public string Name1 => name1;
public string Name2 => name1;
}
CSharpier now supports collection expressions
int[] a = [ 1, 2, 3, 4, 5, 6, 7, 8 ];
Span<int> b = [ 'a', 'b', 'c', 'd', 'e', 'f', 'h', 'i' ];
string[] c =
[
"________________________",
"________________________",
"________________________",
"________________________"
];
int[][] d =
[
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
Thanks go to @meenzen for reporting
Build errors will now display properly when using CSharpier.MSBuild
// 0.25.0
var x = someLongNameField.CallMethod____________________________________().AccessArray[
1
].Property_______________;
// 0.26.0
var x = someLongNameField
.CallMethod____________________________________()
.AccessArray[1]
.Property_______________;
When using cshapier --check
whitespace is now only visible in the following situations
When an otherwise empty line contains whitespace
----------------------------- Expected: Around Line 4 -----------------------------
private string field1;
private string field2;
----------------------------- Actual: Around Line 4 -----------------------------
private string field1;
····
private string field2;
When a line has extra trailing whitespace
----------------------------- Expected: Around Line 3 -----------------------------
{
private string field1;
}
----------------------------- Actual: Around Line 3 -----------------------------
{
private string field1;····
}
When CSharpier.MSBuild ran into a failed csharpier check, it was not encoding the std-error output with UTF8. This resulted in messages such as
----------------------------- Expected: Around Line 3 -----------------------------
{
┬╖┬╖┬╖┬╖private┬╖string┬╖field1;
}
----------------------------- Actual: Around Line 3 -----------------------------
{
┬╖┬╖┬╖┬╖private┬╖string┬╖field1;┬╖┬╖┬╖┬╖
}
Thanks go to @Tyrrrz for reporting
// input
var rawLiteralWithExpressionThatWeDontFormat = new StringContent(
// this comment shouldn't go away
$$"""
{
"params": "{{searchFilter switch
{
SearchFilter.Video => "EgIQAQ%3D%3D",
_ => null
}}}"
}
"""
);
// 0.25.0
var rawLiteralWithExpressionThatWeDontFormat = new StringContent(
$$"""
{
"params": "{{searchFilter switch
{
SearchFilter.Video => "EgIQAQ%3D%3D",
_ => null
}}}"
}
"""
);
Thanks go to @Tyrrrz for reporting
CSharpier now supports the following options for line endings. The default is auto
Thanks go to @phuhl for the feature request
// 0.25.0
if (
someLongStatement == true || someOtherStatement________________________________ == false
)
// 0.26.0
if (someLongStatement == true || someOtherStatement________________________________ == false)
Thanks go to @Nixxen for reporting
// 0.25.0
foreach (var subsequence in sequence)
foreach (var item in subsequence)
item.DoSomething();
// 0.26.0
foreach (var subsequence in sequence)
foreach (var item in subsequence)
item.DoSomething();
Thanks go to @Rudomitori for the contribution
Full Changelog: https://github.com/belav/csharpier/compare/0.25.0...0.26.0
Published by belav about 1 year ago
Published by belav over 1 year ago
The preprocessorSymbolSets
configuration option is no longer supported.
CSharpier can now parse and format the full range of #if
preprocessor statements so it is no longer required.
// 0.24.2 - supported some basic versions of #if
#if DEBUG
// some code
#endif
// 0.25.0 - supports the full range of #if including nested statements
// would require the use of the preprocessorSymbolSets configuration option previously
#if (DEBUG && !NET48) || MONO
// some code
#if NET6_0
// some other code
#endif
#endif
CSharpier will now sort modifiers according to the defaults for IDE0036
// input
public override async Task Method1() { }
async public override Task Method2() { }
// output
public override async Task Method1() { }
public override async Task Method2() { }
Thanks go to @glmnet for the contribution
CSharpier now supports formatting
Primary Constructors,
Alias any typ, and
Default lambda parameters
CSharpier now supports --loglevel
with the CLI and CSharpier_LogLevel
for MSBuild. This changes the level of logging output. Valid options are:
Thanks go to @samtrion for the suggestion
CSharpier was not honoring lines that appeared before unsafe
// input
var x = 1;
unsafe
{
// should retain empty line
}
// 0.24.2
var x = 1;
unsafe
{
// should retain empty line
}
// 0.25.0
var x = 1;
unsafe
{
// should retain empty line
}
Thanks go to @fgimian for reporting the bug
In some instances it is desirable to completely bypass CSharpier.MsBuild, this can now be done with the CSharpier_Bypass
property.
dotnet publish -c release -o /app --no-restore /p:CSharpier_Bypass=true
Thanks go to @OneCyrus for the suggestion
CSharpier is now strong name signed so that it can be used in packages that are strong name signed.
Thanks go to @TwentyFourMinutes for the suggestions and to @goelhardik for strong name signing Ignore
CSharpier will no longer format cs
files that are in an obj
folder.
When CSharpier.MsBuild was in a csproj that had multiple target frameworks, it would run once for each target framework. It will now run just a single time.
CSharpier.MsBuild was not running correctly when used in a project that had centrally managed package version.
Thanks go to @adc-cjewett for reporting the bug
With useTabs: true
, CSharpier was formatting multiline comments with a space instead of a tab.
// input
public class Foo
{
/**
* comment
*/
public class Bar { }
}
// 0.24.1
public class Foo
{
/**
* comment
*/
public class Bar { }
}
// 0.25.0
public class Foo
{
/**
* comment
*/
public class Bar { }
}
Thanks go to @MonstraG for reporting the bug.
CSharpier now adds an empty line after file scoped namespaces if there is not already one
// input
namespace Namespace;
using System;
// 0.25.0
namespace Namespace;
using System;
Full Changelog: https://github.com/belav/csharpier/compare/0.24.2...0.25.0
Published by belav over 1 year ago
In a case where
// csharpier-ignore
on a multi-line statement#if DEBUG
)CSharpier would end up formatting the file with CRLF
on the // csharpier-ignore
statement but LF
in the rest of the file. The file would then fail the formatting check.
Thanks go to @pingzing for the bug report and detailed reproduction steps.
Full Changelog: https://github.com/belav/csharpier/compare/0.24.1...0.24.2
Published by belav over 1 year ago
// input & expected output
// csharpier-ignore
public string Example
{
get
{
if (_example is not null)
return _example;
var number = Random.Shared.Next();
return _example = number.ToString();
}
}
// 0.24.0
// csharpier-ignore
public string Example
{
get
{
if (_example is not null)
return _example;
var number = Random.Shared.Next();
return _example = number.ToString();
}
}
Thanks go to @Pentadome for reporting the regression bug.
Published by belav over 1 year ago
// input & expected output
return list switch
{
[var elem] => elem * elem,
[] => 0,
[..] elems => elems.Sum(e => e + e),
};
// 0.23.0
return list switch
{
[var elem] => elem * elem,
[] => 0,
[..] => elems.Sum(e => e + e),
};
Thanks go to @Dragemil for reporting the bug
CSharpier.MSBuild would throw an exception when building a project if the username had a space, or if the project path had a space.
Thanks go to @ooo2003003v2 for reporting the bug.
// input & expected output
if (
e is
#pragma warning disable CS0618
BadHttpRequestException
#pragma warning restore CS0618
{
Message: "______________________________________________________________________________________________________________"
}
) { }
// 0.23.0
if (
e is
#pragma warning disable CS0618
BadHttpRequestException
#pragma warning restore CS0618
{
Message: "______________________________________________________________________________________________________________"
}
) { }
Thanks go to @Denton-L for reporting the bug
// input
public class AttributesAndMethods
{
// csharpier-ignore - only the first attribute
[Attribute ]
[Attribute ]
public void MethodThatShouldFormat() { }
[Attribute]
// csharpier-ignore - only the second attribute
[Attribute ]
public void MethodThatShouldFormat() { }
[Attribute ]
[Attribute ]
// csharpier-ignore - just the method
public void MethodThatShouldNotFormat( ) { }
}
// 0.23.0
public class AttributesAndMethods
{
// csharpier-ignore - only the first attribute
[Attribute ]
[Attribute ]
public void MethodThatShouldFormat() { }
[Attribute]
// csharpier-ignore - only the second attribute
[Attribute]
public void MethodThatShouldFormat() { }
[Attribute]
[Attribute]
// csharpier-ignore - just the method
public void MethodThatShouldNotFormat() { }
}
// 0.24.0
public class AttributesAndMethods
{
// csharpier-ignore - only the first attribute
[Attribute ]
[Attribute]
public void MethodThatShouldFormat() { }
[Attribute]
// csharpier-ignore - only the second attribute
[Attribute]
public void MethodThatShouldFormat() { }
[Attribute]
[Attribute]
// csharpier-ignore - just the method
public void MethodThatShouldNotFormat() { }
}
Thanks go to @Billuc for reporting the bug
// input & expected output
void MethodName()
{
// csharpier-ignore-start
var packet = new List<byte>();
packet.Add(0x0f); packet.Add(0x00);
packet.Add(0x00); packet.Add(0x00);
// csharpier-ignore-end
}
// 0.23.0
void MethodName()
{
// csharpier-ignore-start
var packet = new List<byte>();
packet.Add(0x0f);
packet.Add(0x00);
packet.Add(0x00);
packet.Add(0x00);
// csharpier-ignore-end
}
Thanks go to @Billuc for reporting the bug
Scoped variables are a language proposal. CSharpier has some support for printing unrecognized syntax nodes but the validation logic didn't account for them and would throw an exception
scoped Span<byte> span;
Thanks go to @Dragemil for reporting the bug
CSharpier now supports printing commends on unrecognized nodes.
// comment on unrecognized node
scoped Span<byte> span;
Full Changelog: https://github.com/belav/csharpier/compare/0.23.0...0.24.0
Published by belav over 1 year ago
Previously CodeFormatter.Format(unformattedCode)
and its overloads returned only the formatted code. It now returns a result object.
public class CodeFormatterResult
{
public string Code { get; }
public IEnumerable<Diagnostic> CompilationErrors { get; }
}
This is a breaking change. There were also a number of types that should not have been public
that were made internal
.
Thanks go to @verdverm for the suggestion
It is now possible to include a suffix on csharpier-ignore
comments. The description must be seperated from the comment by at least one - character.
// csharpier-ignore - class copied as-is from another project
public class Unformatted {
private string unformatted;
}
// csharpier-ignore-start -- class copied as-is from another project
public class Unformatted1 { }
public class Unformatted2 { }
// csharpier-ignore-end
Thanks go to @strepto for the suggestion
// 0.22.1
typeof(AnExceptionallyLongAndElaborateClassNameToMakeAnExampleRegardingOpenGenerics<
,
>).MakeGenericType(typeof(string), typeof(int));
// 0.23.0
typeof(AnExceptionallyLongAndElaborateClassNameToMakeAnExampleRegardingOpenGenerics<,>).MakeGenericType(
typeof(string),
typeof(int)
);
Thanks go to @jonstodle for reporting the issue
Previously the preceding whitespace was left as is on #region
and #endregion
which resulted undesired formatting.
// 0.22.1
public class ClassName
{
#region Ugly methods
public int LongUglyMethod()
{
return 42;
}
#endregion
}
// 0.23.0
public class ClassName
{
#region Ugly methods
public int LongUglyMethod()
{
return 42;
}
#endregion
}
Thanks go to @jods4 for reporting the issue
// 0.22.1
return from i in Enumerable.Range(0, 10)
let i2 = i * i
where i2 < 100
select new { Square = i2, Root = i };
// 0.23.0
return from i in Enumerable.Range(0, 10)
let i2 = i * i
where i2 < 100
select new { Square = i2, Root = i };
Thanks go to @jods4 for reporting the issue
// 0.22.1
var dictionaryInitializer = new Dictionary<int, string> { { 1, "" }, { 2, "a" }, { 3, "b" } };
int[,,] cube = { { { 111, 112 }, { 121, 122 } }, { { 211, 212 }, { 221, 222 } } };
int[][] jagged = { { 111 }, { 121, 122 } };
// 0.23.0
var dictionaryInitializer = new Dictionary<int, string>
{
{ 1, "" },
{ 2, "a" },
{ 3, "b" }
};
int[,,] cube =
{
{
{ 111, 112 },
{ 121, 122 }
},
{
{ 211, 212 },
{ 221, 222 }
}
};
int[][] jagged =
{
{ 111 },
{ 121, 122 }
};
// 0.22.1
var someObject = new SomeObject { SomeArray = new SomeOtherObject[]
{
new SomeOtherObject { SomeProperty = 1 },
new SomeOtherObject()
}.CallMethod().CallMethod() };
// 0.23.0
var someObject = new SomeObject
{
SomeArray = new SomeOtherObject[]
{
new SomeOtherObject { SomeProperty = 1 },
new SomeOtherObject()
}
.CallMethod()
.CallMethod()
};
Thanks go to @shocklateboy92 for reporting the issue
It is now possible to pass --config-path
to the cli for cases where it is not in the root or you want to bypass the auto location and speed up formatting requests.
dotnet csharpier . --config-path "./config/.csharpierrc"
Thanks go to @bdovaz for the suggestion
It is now possible to add blank lines in query syntax expressions which can aid in readability
var result = await (
from post in dbContext.Posts
join blog in dbContext.Blogs on post.BlogId equals blog.Id
let count = dbContext.Posts.Count(p => p.Name == post.Name)
where post.Id == 1
select new
{
Post = post,
Blog = blog,
SamePostNameCount = count
}
)
.AsNoTracking()
.FirstAsync();
Thanks go to @TwentyFourMinutes for the suggestion
// 0.22.1
class ClassName
{
public void MethodName()
{
#if !IF_STATEMENT_HERE_SHOULD_NOT_BREAK_INVOCATION_AFTER_ENDIF
if (true)
{
return;
}
#endif
SomeObject
.CallMethod()
.CallOtherMethod(shouldNotBreak);
}
}
// 0.23.0
class ClassName
{
public void MethodName()
{
#if !IF_STATEMENT_HERE_SHOULD_NOT_BREAK_INVOCATION_AFTER_ENDIF
if (true)
{
return;
}
#endif
SomeObject.CallMethod().CallOtherMethod(shouldNotBreak);
}
}
Full Changelog: https://github.com/belav/csharpier/compare/0.22.0...0.23.0
Published by belav over 1 year ago
Thanks to @BenasB for reporting the issue
Published by belav almost 2 years ago
This fix auto selects net7.0
for projects that do not target net6.0
or net7.0
. This means the CSharpier_FrameworkVersion
property is only required if a project is targeting < net6.0
and net7.0
is not installed.
Thanks go to @samtrion for submitting the fix.
Full Changelog: https://github.com/belav/csharpier/compare/0.21.1...0.22.1
Published by belav almost 2 years ago
Previously UTF.Unknown was used to try to determine file encodings.
This was problematic because if a file was too small it would not properly detect the encoding.
public enum MeetingLocation
{
Café,
Restaurant
}
This file saved as UTF8 would be detected as SBCSCodePageEncoding and result in CSharpier trying to parse the following file
public enum MeetingLocation
{
Café,
Restaurant
}
CSharpier now only supports UTF8 & UTF8-BOM files. This is consistent with the IDE plugins, which stream files to CSharpier as UTF8.
Thanks go to @Meligy for reporting the problem.
CSharpier.MSBuild now multi-targets net6.0 and net7.0. As a side effect of multi-targeting, the CSharpier_FrameworkVersion
property is now required for projects that do not target net6.0
or net7.0
. See https://csharpier.com/docs/MsBuild#target-frameworks
Thanks go to @OneCyrus for reporting it
When projects referencing CSharpier.MsBuild were reloaded, they would get the error "Specified condition "$(CSharpier_Check)" evaluates to "" instead of a boolean" and fail to load.
Thanks go to @samtrion for submitting the fix.
CSharpier did not have proper support for the new c# 11 slice pattern. When a slice contained a pattern, that pattern would be lost.
// input
var someValue = someString is [var firstCharacter, .. var rest];
// 0.21.0
var someValue = someString is [var firstCharacter, ..];
// 0.22.0
var someValue = someString is [var firstCharacter, .. var rest];
Thanks go to @domn1995 for reporting it
When an interpolated string contained a comment within an expression, CSharpier was inserting a line break that resulted in invalid code.
// input
var trailingComment = $"{someValue /* Comment shouldn't cause new line */}";
// 0.21.0
var trailingComment = $"{someValue /* Comment shouldn't cause new line */
}";
// 0.22.0
var trailingComment = $"{someValue /* Comment shouldn't cause new line */}";
Thanks go to @IT-CASADO for reporting it
// 0.21.0
public class SimpleGeneric<T> where T : new() { }
// 0.22.0
public class SimpleGeneric<T>
where T : new() { }
// 0.21.0
public Initializers() : this(true) { }
public Initializers(string value) : base(value) { }
// 0.22.0
public Initializers()
: this(true) { }
public Initializers(string value)
: base(value) { }
Full Changelog: https://github.com/belav/csharpier/compare/0.21.0...0.22.0
Published by belav almost 2 years ago
CSharpier now supports a file scoped type
file class FileScopedClass
{
// implementation
}
In some instances csharpier was removing empty lines in csharpier-ignore
blocks of code
// input
public class KeepLines1
{
// csharpier-ignore-start
private string first;
private string second;
// csharpier-ignore-end
}
// 0.20.0
public class KeepLines1
{
// csharpier-ignore-start
private string first;private string second;
// csharpier-ignore-end
}
Thanks go to @MonstraG for reporting it
// 0.20.0
var result = await from thing in Things
from otherThing in OtherThings
from finalThing in SomethingAsync(thing, otherThing)
select finalThing;
// 0.21.0
var result = await
from thing in Things
from otherThing in OtherThings
from finalThing in SomethingAsync(thing, otherThing)
select finalThing;
Thanks go to @domn1995 for reporting it.
Object initializers break when they have more than two properties. For example
var x = new Thing
{
Post = post,
Blog = blog,
SamePostNameCount = count
};
Anonymous object initializers were not included in this logic prior to 0.21.0
// 0.20.0
var result =
from post in Posts
select new { Post = post, Blog = blog, SamePostNameCount = count };
// 0.21.0
var result =
from post in Posts
select new
{
Post = post,
Blog = blog,
SamePostNameCount = count
};
Thanks go to @TwentyFourMinutes for reporting it.
The CSharpier dotnet tool now works with net6 or net7.
CSharpier was not properly ignoring .cs files when they were in a subfolder of node_modules
Thanks go to @snebjorn for reporting the bug.
Full Changelog: https://github.com/belav/csharpier/compare/0.20.0...0.21.0
Published by belav about 2 years ago
Tuples would break poorly in some cases
// 0.19.2
public async Task<(ILookup<string, int> someLookup, ILookup<int, string> reverseLookup, ILookup<
string,
ClassName
> thirdLookup)> CreateLookups()
{
return (null, null);
}
public void TuplesAsInput(
(int myInt, string myString, ClassName myClassNameInstance, Dictionary<
int,
string
> wordList) inputArgs
)
{
// do something
}
// 0.20.0
public async Task<(
ILookup<string, int> someLookup,
ILookup<int, string> reverseLookup,
ILookup<string, ClassName> thirdLookup
)> CreateLookups()
{
return (null, null);
}
public void TuplesAsInput(
(
int myInt,
string myString,
ClassName myClassNameInstance,
Dictionary<int, string> wordList
) inputArgs
)
{
// do something
}
Thanks go to @BenjaBobs for reporting the bug.
Full Changelog: https://github.com/belav/csharpier/compare/0.19.2...0.20.0
Published by belav about 2 years ago
CSharpier now caches information about files that it has formatted to speed up subsequent runs.
By default the following are used as cache keys and a file is only formatted if one of them has changed.
The cache is stored at [LocalApplicationData]/CSharpier/.formattingCache.
CSharpier now ignores any files within a node_modules folder.
Thanks go to @RichiCoder1 for the suggestion and @SubjectAlpha for the implementation.
// 0.18.0
public class ClassName
{
public int[] SomeArray { get; set; } = { 1, 2, 3 };
}
// 0.19.0
public class MyClass
{
public int[] SomeArray { get; set; } = { 1, 2, 3 };
}
Thanks go to @TiraelSedai for reporting the bug.
Full Changelog: https://github.com/belav/csharpier/compare/0.18.0...0.19.0
Published by belav over 2 years ago
CSharpier can format the following c# 11 features
CSharpier now outputs relative or absolute file paths so that they are clickable in terminals.
dotnet csharpier .
# csharpier 0.17.0
Error Invalid.cs - Failed to compile so was not formatted.
# csharpier 0.18.0
Error ./Invalid.cs - Failed to compile so was not formatted.
dotnet csharpier c:/src
# csharpier 0.17.0
Error Invalid.cs - Failed to compile so was not formatted.
# csharpier 0.18.0
Error c:/src/Invalid.cs - Failed to compile so was not formatted.
Thanks go to @dlech
// input
var someValue =
$@"
{
// comment
"hi"
}
";
// 0.17.0
var someValue =
$@"
{
// comment "hi"}
";
// 0.18.0
var someValue =
$@"
{
// comment
"hi"
}
";
Thanks go to @ivan-razorenov
CSharpier now has the ability to ignore a range of statements or members. See Ignore for more details
// csharpier-ignore-start
var unformatted = true;
var unformatted = true;
// csharpier-ignore-end
Thanks go to @pingzing
Full Changelog: https://github.com/belav/csharpier/compare/0.17.0...0.18.0
Published by belav over 2 years ago
Full Changelog: https://github.com/belav/csharpier/compare/0.16.0...0.17.0
Published by belav over 2 years ago
Full Changelog: https://github.com/belav/csharpier/compare/0.15.1...0.16.0
Published by belav over 2 years ago
CSharpier.MsBuild
now requires .NET6 #565
Full Changelog: https://github.com/belav/csharpier/compare/0.14.0...0.15.0