Skip to content

Releases: belav/csharpier

Rider 1.5.0-beta2

20 Nov 22:58
Compare
Choose a tag to compare
Rider 1.5.0-beta2 Pre-release
Pre-release

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.

0.26.2

16 Nov 04:41
d01362a
Compare
Choose a tag to compare

0.26.2

What's Changed

CSharpier.MsBuild does not support DotNet 8 #1012

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 System using directives should be sorted first #1003

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: 0.26.1...0.26.2

0.26.1

09 Nov 03:23
3d5768a
Compare
Choose a tag to compare

What's Changed

Editorconfig with duplicated sections was freezing IDE's #989

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.

A .csharpierrc file anywhere above a file now takes priority over any .editorconfig #987

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: 0.26.0...0.26.1

0.26.0

06 Nov 23:15
70db9c7
Compare
Choose a tag to compare

What's Changed

EditorConfig Support

CSharpier will now read configuration options from an .editorconfig. See https://csharpier.com/docs/Configuration for more details.

Net8 Support

CSharpier now supports the .net8 sdk. It still supports net6 and net7.

Sorting of using directives #661

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

Remove line before the content of a bracketless if/else statement #979

// 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

Support C# 12 primary constructors on structs #969

CSharpier now supports primary constructors on structs

public struct NamedItem2(
    string name1,
    string name2
)
{
    public string Name1 => name1;
    public string Name2 => name1;
}

Support C# 12 collection expressions [#964](#964

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

MSBuild - when a file fails to compile csharpier interferes with getting you clickable links to the compilation errors. #957

Build errors will now display properly when using CSharpier.MSBuild

Format element access properly in long invocation chains #956

// 0.25.0
var x = someLongNameField.CallMethod____________________________________().AccessArray[
    1
].Property_______________;

// 0.26.0
var x = someLongNameField
    .CallMethod____________________________________()
    .AccessArray[1]
    .Property_______________;

Improvements to visible whitespace in console output. #953

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;····
}

MSBuild is not encoding using UTF8 #947

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

Comment inside raw string literal is lost when file is formatted. #937

// 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

Allow line endings to be configurable #935

CSharpier now supports the following options for line endings. The default is auto

  • "auto" - Maintain existing line endings (mixed values within one file are normalised by looking at what's used after the first line)
  • "lf" – Line Feed only (\n), common on Linux and macOS as well as inside git repos
  • "crlf" - Carriage Return + Line Feed characters (\r\n), common on Windows

Thanks go to @phuhl for the feature request

Avoid breaking only around binary expression but not binary expression itself #924

// 0.25.0
if (
    someLongStatement == true || someOtherStatement________________________________ == false
)

// 0.26.0
if (someLongStatement == true || someOtherStatement________________________________ == false)

Thanks go to @Nixxen for reporting

Nested loops without brackets should not be indented #867

// 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: 0.25.0...0.26.0

Rider 1.3.11-beta1

27 Sep 03:05
Compare
Choose a tag to compare
Rider 1.3.11-beta1 Pre-release
Pre-release
rider-1.3.11-beta1

Try writing to the stream a few times

0.25.0

25 Jun 15:38
21bc71d
Compare
Choose a tag to compare

Breaking Changes

Improve if directive formatting #404

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

What's Changed

Sort Modifiers #725

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

Support c# 12 features #883

CSharpier now supports formatting
Primary Constructors,
Alias any typ, and
Default lambda parameters

Support for log levels #875

CSharpier now supports --loglevel with the CLI and CSharpier_LogLevel for MSBuild. This changes the level of logging output. Valid options are:

  • None
  • Error
  • Warning
  • Information (default)
  • Debug

Thanks go to @samtrion for the suggestion

CSharpier removes blank line before unsafe block #917

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

Adding ability to bypass CSharpier when using CSharpier.MsBuild #914

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

Strong Name Sign Assemblies #911

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

Don't format files in obj folders #910

CSharpier will no longer format cs files that are in an obj folder.

CSharpier.MsBuild runs once for each framework, can it be more efficient. #900

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 returns exit code 1 when ManagePackageVersionsCentrally is set to true #898

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

Multiline comments always indented with spaces when formatting with tabs #891

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.

File scoped namespaces should be followed by a blank line #861

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: 0.24.2...0.25.0

0.24.2

05 May 02:35
0cd093e
Compare
Choose a tag to compare

What's Changed

csharpier-ignore comments force CRLF line endings #884

In a case where

  • a file on windows (which defaults to CRLF) contained only LF
  • the file contained // csharpier-ignore on a multi-line statement
  • the file was formatted in multiple passes due to preprocessor symbols (such as an #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: 0.24.1...0.24.2

0.24.1

26 Apr 16:23
6ab7e3e
Compare
Choose a tag to compare

What's Changed

0.24.0 Regression csharpier-ignore causes blank lines between statements to be removed. #879

// 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.

0.24.0

26 Apr 03:34
a066013
Compare
Choose a tag to compare

What's Changed

Formatting named list patterns loses code and causes compilation error #876

// 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 does not support usernames or project paths with spaces #872

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.

#pragma with long line introduces extra line break #865

// 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

Better support for ignore on method attributes #848

// 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

Ranged ignore applies some formatting when multiple statements are on a line #846

// 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

Support scoped variables (better handling of unrecognized syntax nodes) #839

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

Unrecognized syntax nodes lose comments #869

CSharpier now supports printing commends on unrecognized nodes.

// comment on unrecognized node
scoped Span<byte> span;

Full Changelog: 0.23.0...0.24.0

0.23.0

06 Mar 22:54
a8c1c6a
Compare
Choose a tag to compare

0.23.0

Breaking Changes

Make compile errors public when using CSharpier.Core #799

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

What's Changed

Allow comment-description suffix on csharpier-ignore comments #835

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

Fix formatting for open generics #832

// 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

#region should be indented based on context #812

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

Return statement followed by linq query syntax not indenting correctly #811

// 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

Array and dictionary initializers should break in some cases to improve readability #809

// 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 }
};

List initializer inside object initializer breaks poorly #802

// 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

Allow passing --config-path to cli #777

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

Allow blank lines in query syntax #754

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

#if causes line after it to break when it contains an if #666

// 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: 0.22.0...0.23.0