From 581ed20109d6b04019c4ba72dd3d418ca3cf6ef4 Mon Sep 17 00:00:00 2001 From: Tomohisa Tanaka Date: Sun, 30 Aug 2020 20:33:55 +0900 Subject: [PATCH 1/6] Add NoSpaceAfterBrace and NoSpaceBeforeBrace analyzers. --- .../Spacing/NoSpaceAfterBrace/AnalyzerTest.cs | 39 ++++++ .../Spacing/NoSpaceAfterBrace/Code.cs | 34 +++++ .../Spacing/NoSpaceAfterBrace/CodeFix.cs | 26 ++++ .../Spacing/NoSpaceAfterBrace/Okay.cs | 35 +++++ .../NoSpaceBeforeBrace/AnalyzerTest.cs | 39 ++++++ .../Spacing/NoSpaceBeforeBrace/Code.cs | 37 +++++ .../Spacing/NoSpaceBeforeBrace/CodeFix.cs | 26 ++++ .../Spacing/NoSpaceBeforeBrace/Okay.cs | 35 +++++ .../StyleChecker.Test.csproj | 24 ++++ .../Spacing/NoSpaceAfterBrace/Analyzer.cs | 113 +++++++++++++++ .../Spacing/NoSpaceAfterBrace/CodeFixer.cs | 59 ++++++++ .../NoSpaceAfterBrace/Resources.Designer.cs | 100 +++++++++++++ .../Spacing/NoSpaceAfterBrace/Resources.resx | 132 ++++++++++++++++++ .../NoSpaceAfterSemicolon/CodeFixer.cs | 3 + .../Spacing/NoSpaceBeforeBrace/Analyzer.cs | 117 ++++++++++++++++ .../Spacing/NoSpaceBeforeBrace/CodeFixer.cs | 59 ++++++++ .../NoSpaceBeforeBrace/Resources.Designer.cs | 100 +++++++++++++ .../Spacing/NoSpaceBeforeBrace/Resources.resx | 132 ++++++++++++++++++ StyleChecker/StyleChecker/Spacing/TokenFix.cs | 74 ++++++++++ StyleChecker/StyleChecker/StyleChecker.csproj | 18 +++ StyleChecker/StyleChecker/Syntaxes.cs | 2 +- doc/rules/NoSpaceAfterBrace.md | 79 +++++++++++ doc/rules/NoSpaceBeforeBrace.md | 79 +++++++++++ 23 files changed, 1361 insertions(+), 1 deletion(-) create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/AnalyzerTest.cs create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Code.cs create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/CodeFix.cs create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/AnalyzerTest.cs create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Code.cs create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/CodeFix.cs create mode 100644 StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.Designer.cs create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.resx create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.Designer.cs create mode 100644 StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.resx create mode 100644 StyleChecker/StyleChecker/Spacing/TokenFix.cs create mode 100644 doc/rules/NoSpaceAfterBrace.md create mode 100644 doc/rules/NoSpaceBeforeBrace.md diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/AnalyzerTest.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/AnalyzerTest.cs new file mode 100644 index 00000000..5a98b5d0 --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/AnalyzerTest.cs @@ -0,0 +1,39 @@ +namespace StyleChecker.Test.Spacing.NoSpaceAfterBrace +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using StyleChecker.Spacing.NoSpaceAfterBrace; + using StyleChecker.Test.Framework; + + [TestClass] + public sealed class AnalyzerTest : CodeFixVerifier + { + public AnalyzerTest() + : base(new Analyzer(), new CodeFixer()) + { + } + + [TestMethod] + public void Empty() + => VerifyDiagnostic("", Atmosphere.Default); + + [TestMethod] + public void Okay() + { + var code = ReadText("Okay"); + VerifyDiagnostic(code, Atmosphere.Default); + } + + [TestMethod] + public void Code() + { + var code = ReadText("Code"); + var codeFix = ReadText("CodeFix"); + static Result Expected(Belief b) => b.ToResult( + Analyzer.DiagnosticId, + m => $"A white space is needed after '{m}'"); + + VerifyDiagnosticAndFix( + code, Atmosphere.Default, Expected, codeFix); + } + } +} diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Code.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Code.cs new file mode 100644 index 00000000..cf371208 --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Code.cs @@ -0,0 +1,34 @@ +#pragma warning disable CS0162 + +namespace Application +{ + using System; + + public sealed class Code + { + public void NG() + { + string[] array = {"" }; + //@ ^{ + + Action doNothing = () => {return; }; + //@ ^{ + + if (array is {Length: 0 }z) + //@ ^{ + //@ ^} + { + } + + if (true) {return; }else{} + //@ ^{ + //@ ^} + + do {}while (false); + //@ ^} + + {}; + //@ ^} + } + } +} diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/CodeFix.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/CodeFix.cs new file mode 100644 index 00000000..4af58517 --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/CodeFix.cs @@ -0,0 +1,26 @@ +#pragma warning disable CS0162 + +namespace Application +{ + using System; + + public sealed class Code + { + public void NG() + { + string[] array = { "" }; + + Action doNothing = () => { return; }; + + if (array is { Length: 0 } z) + { + } + + if (true) { return; } else{} + + do {} while (false); + + {} ; + } + } +} diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs new file mode 100644 index 00000000..5bd6b39c --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs @@ -0,0 +1,35 @@ +namespace Application +{ + using System; + + public sealed class Okay + { + public void Basic() + { + if (true) + { + } + var array = new[] { "" }; + var array2 = new[] { + "" }; + var array3 = new[] + { + "", + }; + var array4 = new[] { new[] { "" }, }; + Action doNothing = () => {}; + if (array is { Length: 0 } z) + { + } + if (array is {} e) + { + } + + static void M(string[] a) + { + } + + M(new[] { "" }); + } + } +} diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/AnalyzerTest.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/AnalyzerTest.cs new file mode 100644 index 00000000..7248e153 --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/AnalyzerTest.cs @@ -0,0 +1,39 @@ +namespace StyleChecker.Test.Spacing.NoSpaceBeforeBrace +{ + using Microsoft.VisualStudio.TestTools.UnitTesting; + using StyleChecker.Spacing.NoSpaceBeforeBrace; + using StyleChecker.Test.Framework; + + [TestClass] + public sealed class AnalyzerTest : CodeFixVerifier + { + public AnalyzerTest() + : base(new Analyzer(), new CodeFixer()) + { + } + + [TestMethod] + public void Empty() + => VerifyDiagnostic("", Atmosphere.Default); + + [TestMethod] + public void Okay() + { + var code = ReadText("Okay"); + VerifyDiagnostic(code, Atmosphere.Default); + } + + [TestMethod] + public void Code() + { + var code = ReadText("Code"); + var codeFix = ReadText("CodeFix"); + static Result Expected(Belief b) => b.ToResult( + Analyzer.DiagnosticId, + m => $"A white space is needed before '{m}'"); + + VerifyDiagnosticAndFix( + code, Atmosphere.Default, Expected, codeFix); + } + } +} diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Code.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Code.cs new file mode 100644 index 00000000..3aa6432c --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Code.cs @@ -0,0 +1,37 @@ +#pragma warning disable CS0162 + +namespace Application +{ + using System; + + public sealed class Code + { + public void NG() + { + string[] array ={ ""}; + //@ ^{ + //@ ^} + + Action doNothing = () =>{ return;}; + //@ ^{ + //@ ^} + + if (array is{ Length: 0} z) + //@ ^{ + //@ ^} + { + } + + if (true){ return;} else{} + //@ ^{ + //@ ^} + //@ ^{ + + do{} while (false); + //@ ^{ + + ;{} + //@ ^{ + } + } +} diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/CodeFix.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/CodeFix.cs new file mode 100644 index 00000000..d3e2305a --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/CodeFix.cs @@ -0,0 +1,26 @@ +#pragma warning disable CS0162 + +namespace Application +{ + using System; + + public sealed class Code + { + public void NG() + { + string[] array = { "" }; + + Action doNothing = () => { return; }; + + if (array is { Length: 0 } z) + { + } + + if (true) { return; } else {} + + do {} while (false); + + ; {} + } + } +} diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs new file mode 100644 index 00000000..5bd6b39c --- /dev/null +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs @@ -0,0 +1,35 @@ +namespace Application +{ + using System; + + public sealed class Okay + { + public void Basic() + { + if (true) + { + } + var array = new[] { "" }; + var array2 = new[] { + "" }; + var array3 = new[] + { + "", + }; + var array4 = new[] { new[] { "" }, }; + Action doNothing = () => {}; + if (array is { Length: 0 } z) + { + } + if (array is {} e) + { + } + + static void M(string[] a) + { + } + + M(new[] { "" }); + } + } +} diff --git a/StyleChecker/StyleChecker.Test/StyleChecker.Test.csproj b/StyleChecker/StyleChecker.Test/StyleChecker.Test.csproj index 740ba528..166a27b3 100644 --- a/StyleChecker/StyleChecker.Test/StyleChecker.Test.csproj +++ b/StyleChecker/StyleChecker.Test/StyleChecker.Test.csproj @@ -96,6 +96,12 @@ + + + + + + @@ -420,6 +426,24 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + + + PreserveNewest + PreserveNewest diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs new file mode 100644 index 00000000..58115bdb --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs @@ -0,0 +1,113 @@ +namespace StyleChecker.Spacing.NoSpaceAfterBrace +{ + using System; + using System.Collections.Immutable; + using System.Linq; + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CSharp; + using Microsoft.CodeAnalysis.CSharp.Syntax; + using Microsoft.CodeAnalysis.Diagnostics; + using R = Resources; + + /// + /// NoSpaceAfterBrace analyzer. + /// + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class Analyzer : AbstractAnalyzer + { + /// + /// The ID of this analyzer. + /// + public const string DiagnosticId = "NoSpaceAfterBrace"; + + private const string Category = Categories.Spacing; + private static readonly DiagnosticDescriptor Rule = NewRule(); + + /// + public override ImmutableArray + SupportedDiagnostics => ImmutableArray.Create(Rule); + + /// + private protected override void Register(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.RegisterSyntaxTreeAction(SyntaxTreeAction); + } + + private static DiagnosticDescriptor NewRule() + { + var localize = Localizers.Of(R.ResourceManager); + return new DiagnosticDescriptor( + DiagnosticId, + localize(nameof(R.Title)), + localize(nameof(R.MessageFormat)), + Category, + DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: localize(nameof(R.Description)), + helpLinkUri: HelpLink.ToUri(DiagnosticId)); + } + + private static void SyntaxTreeAction( + SyntaxTreeAnalysisContext context) + { + static bool StartsWithSpace(SyntaxTriviaList list) + { + return list.First() + .IsKindOneOf( + SyntaxKind.WhitespaceTrivia, + SyntaxKind.EndOfLineTrivia); + } + + static bool DoesBraceNeedSpace( + SyntaxToken token, + Func otherwiseNext) + { + return token.HasTrailingTrivia + ? !StartsWithSpace(token.TrailingTrivia) + : token.GetNextToken() is {} next + && next.HasLeadingTrivia + ? !StartsWithSpace(next.LeadingTrivia) + : otherwiseNext(next); + } + + static bool DoesCloseBraceNeedSpace(SyntaxToken token) + { + return DoesBraceNeedSpace( + token, + next => !next.IsKindOneOf( + SyntaxKind.None, + SyntaxKind.CloseParenToken, + SyntaxKind.CommaToken) + && !(next.IsKind(SyntaxKind.SemicolonToken) + && !(next.Parent is EmptyStatementSyntax))); + } + + static bool DoesOpenBraceNeedSpace(SyntaxToken token) + { + return DoesBraceNeedSpace( + token, + next => !next.IsKindOneOf( + SyntaxKind.None, + SyntaxKind.CloseBraceToken)); + } + + var root = context.Tree + .GetCompilationUnitRoot(context.CancellationToken); + var leftBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) + && !t.IsMissing + && DoesOpenBraceNeedSpace(t)); + var rightBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) + && !t.IsMissing + && DoesCloseBraceNeedSpace(t)); + var all = leftBraces.Concat(rightBraces); + foreach (var t in all) + { + context.ReportDiagnostic( + Diagnostic.Create(Rule, t.GetLocation(), t.Text)); + } + } + } +} diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs new file mode 100644 index 00000000..3f6b1758 --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs @@ -0,0 +1,59 @@ +namespace StyleChecker.Spacing.NoSpaceAfterBrace +{ + using System.Collections.Immutable; + using System.Composition; + using System.Globalization; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CodeActions; + using Microsoft.CodeAnalysis.CodeFixes; + using R = Resources; + + /// + /// NoSpaceAfterBrace code fix provider. + /// + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixer))] + [Shared] + public sealed class CodeFixer : CodeFixProvider + { + /// + public override ImmutableArray FixableDiagnosticIds + => ImmutableArray.Create(Analyzer.DiagnosticId); + + /// + public override FixAllProvider GetFixAllProvider() + => WellKnownFixAllProviders.BatchFixer; + + /// + public override async Task RegisterCodeFixesAsync( + CodeFixContext context) + { + var localize = Localizers.Of(R.ResourceManager); + var title = localize(nameof(R.FixTitle)) + .ToString(CultureInfo.CurrentCulture); + + var root = await context.Document + .GetSyntaxRootAsync(context.CancellationToken) + .ConfigureAwait(false); + if (root is null) + { + return; + } + + var diagnostic = context.Diagnostics[0]; + var span = diagnostic.Location.SourceSpan; + var token = root.FindToken(span.Start, findInsideTrivia: true); + + Task FixTask(CancellationToken c) + => TokenFix.AddSpaceAfterToken(context.Document, token); + + context.RegisterCodeFix( + CodeAction.Create( + title: title, + createChangedDocument: FixTask, + equivalenceKey: title), + diagnostic); + } + } +} diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.Designer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.Designer.cs new file mode 100644 index 00000000..2f6d2723 --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.Designer.cs @@ -0,0 +1,100 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace StyleChecker.Spacing.NoSpaceAfterBrace { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("StyleChecker.Spacing.NoSpaceAfterBrace.Resources", typeof(Resources).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to A brace should be followed by a white space.. + /// + internal static string Description { + get { + return ResourceManager.GetString("Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Insert a white space.. + /// + internal static string FixTitle { + get { + return ResourceManager.GetString("FixTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A white space is needed after '{0}'. + /// + internal static string MessageFormat { + get { + return ResourceManager.GetString("MessageFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A brace is not followed by a white space.. + /// + internal static string Title { + get { + return ResourceManager.GetString("Title", resourceCulture); + } + } + } +} diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.resx b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.resx new file mode 100644 index 00000000..f93d9e6c --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Resources.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + A brace should be followed by a white space. + + + Insert a white space. + + + A white space is needed after '{0}' + + + A brace is not followed by a white space. + + \ No newline at end of file diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs index fbbb45ae..2d1a7ace 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs @@ -44,6 +44,9 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var span = diagnostic.Location.SourceSpan; var token = root.FindToken(span.Start, findInsideTrivia: true); + // Task FixTask(CancellationToken c) + // => TokenFix.AddSpaceAfterToken(context.Document, token); + var action = CodeAction.Create( title: title, createChangedDocument: Fix(context.Document, root, token), diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs new file mode 100644 index 00000000..907842e5 --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs @@ -0,0 +1,117 @@ +namespace StyleChecker.Spacing.NoSpaceBeforeBrace +{ + using System; + using System.Collections.Immutable; + using System.Linq; + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CSharp; + using Microsoft.CodeAnalysis.Diagnostics; + using R = Resources; + + /// + /// NoSpaceBeforeBrace analyzer. + /// + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class Analyzer : AbstractAnalyzer + { + /// + /// The ID of this analyzer. + /// + public const string DiagnosticId = "NoSpaceBeforeBrace"; + + private const string Category = Categories.Spacing; + private static readonly DiagnosticDescriptor Rule = NewRule(); + + /// + public override ImmutableArray + SupportedDiagnostics => ImmutableArray.Create(Rule); + + /// + private protected override void Register(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.RegisterSyntaxTreeAction(SyntaxTreeAction); + } + + private static DiagnosticDescriptor NewRule() + { + var localize = Localizers.Of(R.ResourceManager); + return new DiagnosticDescriptor( + DiagnosticId, + localize(nameof(R.Title)), + localize(nameof(R.MessageFormat)), + Category, + DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: localize(nameof(R.Description)), + helpLinkUri: HelpLink.ToUri(DiagnosticId)); + } + + private static void SyntaxTreeAction( + SyntaxTreeAnalysisContext context) + { + static bool EndsWithSpace(SyntaxTriviaList list) + { + return list.Last() + .IsKindOneOf( + SyntaxKind.WhitespaceTrivia, + SyntaxKind.EndOfLineTrivia); + } + + static bool IsOnFirstColumn(SyntaxToken token) + { + return token.GetLocation() + .GetLineSpan() + .StartLinePosition + .Character is 0; + } + + static bool DoesBraceNeedSpace( + SyntaxToken token, Func otherwisePrev) + { + return !IsOnFirstColumn(token) + && token.HasLeadingTrivia + ? !EndsWithSpace(token.LeadingTrivia) + : token.GetPreviousToken() is {} prev + && prev.HasTrailingTrivia + ? !EndsWithSpace(prev.TrailingTrivia) + : otherwisePrev(prev); + } + + static bool DoesOpenBraceNeedSpace(SyntaxToken token) + { + return DoesBraceNeedSpace( + token, + prev => !prev.IsKindOneOf( + SyntaxKind.None, + SyntaxKind.OpenParenToken)); + } + + static bool DoesCloseBraceNeedSpace(SyntaxToken token) + { + return DoesBraceNeedSpace( + token, + prev => !prev.IsKindOneOf( + SyntaxKind.None, + SyntaxKind.OpenBraceToken)); + } + + var root = context.Tree + .GetCompilationUnitRoot(context.CancellationToken); + var leftBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) + && !t.IsMissing + && DoesOpenBraceNeedSpace(t)); + var rightBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) + && !t.IsMissing + && DoesCloseBraceNeedSpace(t)); + var all = leftBraces.Concat(rightBraces); + foreach (var t in all) + { + context.ReportDiagnostic( + Diagnostic.Create(Rule, t.GetLocation(), t.Text)); + } + } + } +} diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs new file mode 100644 index 00000000..5d272279 --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs @@ -0,0 +1,59 @@ +namespace StyleChecker.Spacing.NoSpaceBeforeBrace +{ + using System.Collections.Immutable; + using System.Composition; + using System.Globalization; + using System.Threading; + using System.Threading.Tasks; + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CodeActions; + using Microsoft.CodeAnalysis.CodeFixes; + using R = Resources; + + /// + /// NoSpaceBeforeBrace code fix provider. + /// + [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixer))] + [Shared] + public sealed class CodeFixer : CodeFixProvider + { + /// + public override ImmutableArray FixableDiagnosticIds + => ImmutableArray.Create(Analyzer.DiagnosticId); + + /// + public override FixAllProvider GetFixAllProvider() + => WellKnownFixAllProviders.BatchFixer; + + /// + public override async Task RegisterCodeFixesAsync( + CodeFixContext context) + { + var localize = Localizers.Of(R.ResourceManager); + var title = localize(nameof(R.FixTitle)) + .ToString(CultureInfo.CurrentCulture); + + var root = await context.Document + .GetSyntaxRootAsync(context.CancellationToken) + .ConfigureAwait(false); + if (root is null) + { + return; + } + + var diagnostic = context.Diagnostics[0]; + var span = diagnostic.Location.SourceSpan; + var token = root.FindToken(span.Start, findInsideTrivia: true); + + Task FixTask(CancellationToken c) + => TokenFix.AddSpaceBeforeToken(context.Document, token); + + context.RegisterCodeFix( + CodeAction.Create( + title: title, + createChangedDocument: FixTask, + equivalenceKey: title), + diagnostic); + } + } +} diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.Designer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.Designer.cs new file mode 100644 index 00000000..909934f0 --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.Designer.cs @@ -0,0 +1,100 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace StyleChecker.Spacing.NoSpaceBeforeBrace { + using System; + using System.Reflection; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("StyleChecker.Spacing.NoSpaceBeforeBrace.Resources", typeof(Resources).GetTypeInfo().Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to A brace should be preceded by a white space.. + /// + internal static string Description { + get { + return ResourceManager.GetString("Description", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Insert a white space.. + /// + internal static string FixTitle { + get { + return ResourceManager.GetString("FixTitle", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A white space is needed before '{0}'. + /// + internal static string MessageFormat { + get { + return ResourceManager.GetString("MessageFormat", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to A brace is not preceded by a white space.. + /// + internal static string Title { + get { + return ResourceManager.GetString("Title", resourceCulture); + } + } + } +} diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.resx b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.resx new file mode 100644 index 00000000..822a44c8 --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Resources.resx @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + A brace should be preceded by a white space. + + + Insert a white space. + + + A white space is needed before '{0}' + + + A brace is not preceded by a white space. + + \ No newline at end of file diff --git a/StyleChecker/StyleChecker/Spacing/TokenFix.cs b/StyleChecker/StyleChecker/Spacing/TokenFix.cs new file mode 100644 index 00000000..fb9bc983 --- /dev/null +++ b/StyleChecker/StyleChecker/Spacing/TokenFix.cs @@ -0,0 +1,74 @@ +namespace StyleChecker.Spacing +{ + using System.Threading.Tasks; + using Microsoft.CodeAnalysis; + using Microsoft.CodeAnalysis.CSharp; + + /// + /// Provides utility methods for fixing tokens. + /// + public static class TokenFix + { + /// + /// Gets the task that returns a new document created by adding a white + /// space immediately after the specified token in the specified + /// document. + /// + /// + /// The document containing the . + /// + /// + /// The token to add a white space after. + /// + /// + /// The new document. + /// + public static Task AddSpaceAfterToken( + Document document, + SyntaxToken token) + { + var list = token.TrailingTrivia; + var space = SyntaxFactory.ParseTrailingTrivia(" "); + var newList = list.InsertRange(0, space); + var newToken = token.WithTrailingTrivia(newList); + return Replace(document, token, newToken); + } + + /// + /// Gets the task that returns a new document created by adding a white + /// space immediately before the specified token in the specified + /// document. + /// + /// + /// The document containing the . + /// + /// + /// The token to add a white space before. + /// + /// + /// The new document. + /// + public static Task AddSpaceBeforeToken( + Document document, + SyntaxToken token) + { + var list = token.LeadingTrivia; + var space = SyntaxFactory.ParseLeadingTrivia(" "); + var newList = list.AddRange(space); + var newToken = token.WithLeadingTrivia(newList); + return Replace(document, token, newToken); + } + + private static async Task Replace( + Document document, + SyntaxToken token, + SyntaxToken newToken) + { + var root = token.SyntaxTree + .GetRoot(); + var newRoot = root.ReplaceToken(token, newToken); + return await Task.Run(() => document.WithSyntaxRoot(newRoot)) + .ConfigureAwait(false); + } + } +} diff --git a/StyleChecker/StyleChecker/StyleChecker.csproj b/StyleChecker/StyleChecker/StyleChecker.csproj index b2184197..3bf38be9 100644 --- a/StyleChecker/StyleChecker/StyleChecker.csproj +++ b/StyleChecker/StyleChecker/StyleChecker.csproj @@ -183,6 +183,16 @@ True True + + Resources.resx + True + True + + + Resources.resx + True + True + True True @@ -297,6 +307,14 @@ Resources.Designer.cs ResXFileCodeGenerator + + Resources.Designer.cs + ResXFileCodeGenerator + + + Resources.Designer.cs + ResXFileCodeGenerator + ResXFileCodeGenerator Resources.Designer.cs diff --git a/StyleChecker/StyleChecker/Syntaxes.cs b/StyleChecker/StyleChecker/Syntaxes.cs index ebea769c..4c9c39b9 100644 --- a/StyleChecker/StyleChecker/Syntaxes.cs +++ b/StyleChecker/StyleChecker/Syntaxes.cs @@ -54,7 +54,7 @@ public static bool IsKindOneOf( } /// - /// Gets the node of the specified type, corresponging to the specified + /// Gets the node of the specified type, corresponding to the specified /// span. /// /// diff --git a/doc/rules/NoSpaceAfterBrace.md b/doc/rules/NoSpaceAfterBrace.md new file mode 100644 index 00000000..25bd3c3e --- /dev/null +++ b/doc/rules/NoSpaceAfterBrace.md @@ -0,0 +1,79 @@ + +
+ +# NoSpaceAfterBrace + +
+ +![NoSpaceAfterBrace][fig-NoSpaceAfterBrace] + +
+ +## Summary + +A brace (‘`{`’ or ‘`}`’) must be followed by a white +space. + +## Default severity + +Warning + +## Description + +An opening brace (‘`{`’) that is not the last character on the line +must be followed by a single space or a closing brace (‘`}`’). + +A closing brace (‘`}`’) that is not the last character on the line +must be followed by a single space, a closing parenthesis (‘`)`’), +a comma (‘`,`’), or a semicolon (‘`;`’). + +Note that this analyzer and [NoSpaceBeforeBrace](NoSpaceBeforeBrace.md) +analyzer are designed to use them together and replace [SA1012][sa1012] and +[SA1013][sa1013] with them, allowing us to write empty braces +(“`{}`”) as follows: + +```csharp +Action doNothing = () => {}; + +if (maybeString is {} s) +{ + ... +} +``` + +## Code fix + +The code fix provides an option inserting a space after the brace. + +## Example + +### Diagnostic + +```csharp +string[] array = {"" }; + +Action doNothing = () => {return; }; + +if (array is {Length: 0 }z) +{ +} +``` + +### Code fix + +```csharp +string[] array = { "" }; + +Action doNothing = () => { return; }; + +if (array is { Length: 0 } z) +{ +} +``` + +[sa1012]: + https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1012.md +[sa1013]: + https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1013.md +[fig-NoSpaceAfterBrace]: + https://maroontress.github.io/StyleChecker/images/NoSpaceAfterBrace.png diff --git a/doc/rules/NoSpaceBeforeBrace.md b/doc/rules/NoSpaceBeforeBrace.md new file mode 100644 index 00000000..6cd9eebe --- /dev/null +++ b/doc/rules/NoSpaceBeforeBrace.md @@ -0,0 +1,79 @@ + +
+ +# NoSpaceBeforeBrace + +
+ +![NoSpaceBeforeBrace][fig-NoSpaceBeforeBrace] + +
+ +## Summary + +A brace (‘`{`’ or ‘`}`’) must be preceded by a white +space. + +## Default severity + +Warning + +## Description + +An opening brace (‘`{`’) that is not the first character on the +line must be preceded by a single space or an opening parenthesis +(‘`(`’). + +A closing brace (‘`}`’) that is not the first character on the line +must be preceded by a single space or an opening brace (‘`{`’). + +Note that this analyzer and [NoSpaceAfterBrace](NoSpaceAfterBrace.md) analyzer +are designed to use them together and replace [SA1012][sa1012] and +[SA1013][sa1013] with them, allowing us to write empty braces +(“`{}`”) as follows: + +```csharp +Action doNothing = () => {}; + +if (maybeString is {} s) +{ + ... +} +``` + +## Code fix + +The code fix provides an option inserting a space before the brace. + +## Example + +### Diagnostic + +```csharp +string[] array ={ ""}; + +Action doNothing = () =>{ return;}; + +if (array is{ Length: 0} z) +{ +} +``` + +### Code fix + +```csharp +string[] array = { "" }; + +Action doNothing = () => { return; }; + +if (array is { Length: 0 } z) +{ +} +``` + +[sa1012]: + https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1012.md +[sa1013]: + https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1013.md +[fig-NoSpaceBeforeBrace]: + https://maroontress.github.io/StyleChecker/images/NoSpaceBeforeBrace.png From eabe13c9b5302121596d8fffb1de138620b380af Mon Sep 17 00:00:00 2001 From: Tomohisa Tanaka Date: Mon, 7 Sep 2020 02:37:06 +0900 Subject: [PATCH 2/6] Fix NSAB analyzer. --- .../StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs | 5 +++++ .../StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs | 8 ++++++-- doc/rules/NoSpaceAfterBrace.md | 6 ++++-- doc/rules/NoSpaceBeforeBrace.md | 2 +- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs index 5bd6b39c..8718ad5a 100644 --- a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs @@ -30,6 +30,11 @@ static void M(string[] a) } M(new[] { "" }); + + _ = new[] { "" }.ToString(); + _ = new[] { "" }?.ToString(); + _ = new[] { "" }!; + _ = new[] { "" }[0]; } } } diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs index 58115bdb..886d4de9 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs @@ -76,9 +76,13 @@ static bool DoesCloseBraceNeedSpace(SyntaxToken token) return DoesBraceNeedSpace( token, next => !next.IsKindOneOf( - SyntaxKind.None, SyntaxKind.CloseParenToken, - SyntaxKind.CommaToken) + SyntaxKind.CommaToken, + SyntaxKind.DotToken, + SyntaxKind.ExclamationToken, + SyntaxKind.None, + SyntaxKind.OpenBracketToken, + SyntaxKind.QuestionToken) && !(next.IsKind(SyntaxKind.SemicolonToken) && !(next.Parent is EmptyStatementSyntax))); } diff --git a/doc/rules/NoSpaceAfterBrace.md b/doc/rules/NoSpaceAfterBrace.md index 25bd3c3e..28a9a50d 100644 --- a/doc/rules/NoSpaceAfterBrace.md +++ b/doc/rules/NoSpaceAfterBrace.md @@ -25,7 +25,9 @@ must be followed by a single space or a closing brace (‘`}`’). A closing brace (‘`}`’) that is not the last character on the line must be followed by a single space, a closing parenthesis (‘`)`’), -a comma (‘`,`’), or a semicolon (‘`;`’). +an opening bracket (‘`[`’), a comma (‘`,`’), a period +(‘`.`’), an exclamation mark (‘`!`’), a question mark +(‘`?`’), or a semicolon (‘`;`’). Note that this analyzer and [NoSpaceBeforeBrace](NoSpaceBeforeBrace.md) analyzer are designed to use them together and replace [SA1012][sa1012] and @@ -37,7 +39,7 @@ Action doNothing = () => {}; if (maybeString is {} s) { - ... + ⋮ } ``` diff --git a/doc/rules/NoSpaceBeforeBrace.md b/doc/rules/NoSpaceBeforeBrace.md index 6cd9eebe..cdebede4 100644 --- a/doc/rules/NoSpaceBeforeBrace.md +++ b/doc/rules/NoSpaceBeforeBrace.md @@ -37,7 +37,7 @@ Action doNothing = () => {}; if (maybeString is {} s) { - ... + ⋮ } ``` From 78d7e7d8a2aa8c410fd456f148159dc789be0b28 Mon Sep 17 00:00:00 2001 From: Tomohisa Tanaka Date: Mon, 21 Sep 2020 17:11:29 +0900 Subject: [PATCH 3/6] Fix NSAB/NSBB analyzers to ignore braces in interpolation. --- .../Spacing/NoSpaceAfterBrace/Okay.cs | 5 +++++ .../Spacing/NoSpaceBeforeBrace/Okay.cs | 5 +++++ .../Spacing/NoSpaceAfterBrace/Analyzer.cs | 10 +++++++-- .../Spacing/NoSpaceBeforeBrace/Analyzer.cs | 10 +++++++-- StyleChecker/StyleChecker/Syntaxes.cs | 21 +++++++++++++++++++ 5 files changed, 47 insertions(+), 4 deletions(-) diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs index 8718ad5a..bc602a78 100644 --- a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceAfterBrace/Okay.cs @@ -36,5 +36,10 @@ static void M(string[] a) _ = new[] { "" }!; _ = new[] { "" }[0]; } + + public void Interpolation(string m) + { + _ = $"{m}"; + } } } diff --git a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs index 5bd6b39c..e6c8fda6 100644 --- a/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs +++ b/StyleChecker/StyleChecker.Test/Spacing/NoSpaceBeforeBrace/Okay.cs @@ -31,5 +31,10 @@ static void M(string[] a) M(new[] { "" }); } + + public void Interpolation(string m) + { + _ = $"{m}"; + } } } diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs index 886d4de9..f794b633 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs @@ -96,15 +96,21 @@ static bool DoesOpenBraceNeedSpace(SyntaxToken token) SyntaxKind.CloseBraceToken)); } + static bool IsExceptional(SyntaxToken token) + { + return token.IsMissing + || token.Parent.IsKind(SyntaxKind.Interpolation); + } + var root = context.Tree .GetCompilationUnitRoot(context.CancellationToken); var leftBraces = root.DescendantTokens() .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) - && !t.IsMissing + && !IsExceptional(t) && DoesOpenBraceNeedSpace(t)); var rightBraces = root.DescendantTokens() .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) - && !t.IsMissing + && !IsExceptional(t) && DoesCloseBraceNeedSpace(t)); var all = leftBraces.Concat(rightBraces); foreach (var t in all) diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs index 907842e5..7dc7d929 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs @@ -96,15 +96,21 @@ static bool DoesCloseBraceNeedSpace(SyntaxToken token) SyntaxKind.OpenBraceToken)); } + static bool IsExceptional(SyntaxToken token) + { + return token.IsMissing + || token.Parent.IsKind(SyntaxKind.Interpolation); + } + var root = context.Tree .GetCompilationUnitRoot(context.CancellationToken); var leftBraces = root.DescendantTokens() .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) - && !t.IsMissing + && !IsExceptional(t) && DoesOpenBraceNeedSpace(t)); var rightBraces = root.DescendantTokens() .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) - && !t.IsMissing + && !IsExceptional(t) && DoesCloseBraceNeedSpace(t)); var all = leftBraces.Concat(rightBraces); foreach (var t in all) diff --git a/StyleChecker/StyleChecker/Syntaxes.cs b/StyleChecker/StyleChecker/Syntaxes.cs index 4c9c39b9..fa466dcd 100644 --- a/StyleChecker/StyleChecker/Syntaxes.cs +++ b/StyleChecker/StyleChecker/Syntaxes.cs @@ -53,6 +53,27 @@ public static bool IsKindOneOf( return kinds.Any(k => node.IsKind(k)); } + /// + /// Returns whether the SyntaxKind of the specified + /// SyntaxToken is included in the specified SyntaxKinds or + /// not. + /// + /// + /// The SyntaxToken object. + /// + /// + /// SyntaxKind objects. + /// + /// + /// true if the SyntaxKind of + /// is included in , false otherwise. + /// + public static bool IsKindOneOf( + this SyntaxToken token, params SyntaxKind[] kinds) + { + return kinds.Any(k => token.IsKind(k)); + } + /// /// Gets the node of the specified type, corresponding to the specified /// span. From 440d6998d648c6029e0889c703fbdbf5ea7798a3 Mon Sep 17 00:00:00 2001 From: Tomohisa Tanaka Date: Tue, 7 May 2024 22:03:06 +0900 Subject: [PATCH 4/6] Refactor --- .../Spacing/NoSpaceAfterBrace/Analyzer.cs | 206 +++++++++--------- .../Spacing/NoSpaceAfterBrace/CodeFixer.cs | 92 ++++---- .../NoSpaceAfterSemicolon/CodeFixer.cs | 33 +-- .../Spacing/NoSpaceBeforeBrace/Analyzer.cs | 205 +++++++++-------- .../Spacing/NoSpaceBeforeBrace/CodeFixer.cs | 93 ++++---- .../Spacing/SpaceBeforeSemicolon/CodeFixer.cs | 21 +- StyleChecker/StyleChecker/Spacing/TokenFix.cs | 151 +++++++------ 7 files changed, 384 insertions(+), 417 deletions(-) diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs index f794b633..78f2cb29 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/Analyzer.cs @@ -1,123 +1,121 @@ -namespace StyleChecker.Spacing.NoSpaceAfterBrace -{ - using System; - using System.Collections.Immutable; - using System.Linq; - using Microsoft.CodeAnalysis; - using Microsoft.CodeAnalysis.CSharp; - using Microsoft.CodeAnalysis.CSharp.Syntax; - using Microsoft.CodeAnalysis.Diagnostics; - using R = Resources; +namespace StyleChecker.Spacing.NoSpaceAfterBrace; + +using System; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Diagnostics; +using R = Resources; +/// +/// NoSpaceAfterBrace analyzer. +/// +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public sealed class Analyzer : AbstractAnalyzer +{ /// - /// NoSpaceAfterBrace analyzer. + /// The ID of this analyzer. /// - [DiagnosticAnalyzer(LanguageNames.CSharp)] - public sealed class Analyzer : AbstractAnalyzer - { - /// - /// The ID of this analyzer. - /// - public const string DiagnosticId = "NoSpaceAfterBrace"; + public const string DiagnosticId = "NoSpaceAfterBrace"; - private const string Category = Categories.Spacing; - private static readonly DiagnosticDescriptor Rule = NewRule(); + private const string Category = Categories.Spacing; + private static readonly DiagnosticDescriptor Rule = NewRule(); - /// - public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + /// + public override ImmutableArray + SupportedDiagnostics => [Rule]; - /// - private protected override void Register(AnalysisContext context) + /// + private protected override void Register(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.RegisterSyntaxTreeAction(SyntaxTreeAction); + } + + private static DiagnosticDescriptor NewRule() + { + var localize = Localizers.Of(R.ResourceManager); + return new DiagnosticDescriptor( + DiagnosticId, + localize(nameof(R.Title)), + localize(nameof(R.MessageFormat)), + Category, + DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: localize(nameof(R.Description)), + helpLinkUri: HelpLink.ToUri(DiagnosticId)); + } + + private static void SyntaxTreeAction(SyntaxTreeAnalysisContext context) + { + static bool StartsWithSpace(SyntaxTriviaList list) { - context.EnableConcurrentExecution(); - context.RegisterSyntaxTreeAction(SyntaxTreeAction); + return list.First() + .IsKindOneOf( + SyntaxKind.WhitespaceTrivia, + SyntaxKind.EndOfLineTrivia); } - private static DiagnosticDescriptor NewRule() + static bool DoesBraceNeedSpace( + SyntaxToken token, Func otherwiseNext) { - var localize = Localizers.Of(R.ResourceManager); - return new DiagnosticDescriptor( - DiagnosticId, - localize(nameof(R.Title)), - localize(nameof(R.MessageFormat)), - Category, - DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: localize(nameof(R.Description)), - helpLinkUri: HelpLink.ToUri(DiagnosticId)); + return token.HasTrailingTrivia + ? !StartsWithSpace(token.TrailingTrivia) + : token.GetNextToken() is {} next + && next.HasLeadingTrivia + ? !StartsWithSpace(next.LeadingTrivia) + : otherwiseNext(next); } - private static void SyntaxTreeAction( - SyntaxTreeAnalysisContext context) + static bool DoesCloseBraceNeedSpace(SyntaxToken token) { - static bool StartsWithSpace(SyntaxTriviaList list) - { - return list.First() - .IsKindOneOf( - SyntaxKind.WhitespaceTrivia, - SyntaxKind.EndOfLineTrivia); - } - - static bool DoesBraceNeedSpace( - SyntaxToken token, - Func otherwiseNext) - { - return token.HasTrailingTrivia - ? !StartsWithSpace(token.TrailingTrivia) - : token.GetNextToken() is {} next - && next.HasLeadingTrivia - ? !StartsWithSpace(next.LeadingTrivia) - : otherwiseNext(next); - } - - static bool DoesCloseBraceNeedSpace(SyntaxToken token) - { - return DoesBraceNeedSpace( - token, - next => !next.IsKindOneOf( - SyntaxKind.CloseParenToken, - SyntaxKind.CommaToken, - SyntaxKind.DotToken, - SyntaxKind.ExclamationToken, - SyntaxKind.None, - SyntaxKind.OpenBracketToken, - SyntaxKind.QuestionToken) - && !(next.IsKind(SyntaxKind.SemicolonToken) - && !(next.Parent is EmptyStatementSyntax))); - } - - static bool DoesOpenBraceNeedSpace(SyntaxToken token) - { - return DoesBraceNeedSpace( - token, - next => !next.IsKindOneOf( + return DoesBraceNeedSpace( + token, + next => !next.IsKindOneOf( + SyntaxKind.CloseParenToken, + SyntaxKind.CommaToken, + SyntaxKind.DotToken, + SyntaxKind.ExclamationToken, SyntaxKind.None, - SyntaxKind.CloseBraceToken)); - } + SyntaxKind.OpenBracketToken, + SyntaxKind.QuestionToken) + && !(next.IsKind(SyntaxKind.SemicolonToken) + && next.Parent is not EmptyStatementSyntax)); + } + + static bool DoesOpenBraceNeedSpace(SyntaxToken token) + { + return DoesBraceNeedSpace( + token, + next => !next.IsKindOneOf( + SyntaxKind.None, + SyntaxKind.CloseBraceToken)); + } - static bool IsExceptional(SyntaxToken token) - { - return token.IsMissing - || token.Parent.IsKind(SyntaxKind.Interpolation); - } + static bool IsExceptional(SyntaxToken token) + { + return token.IsMissing + || token.Parent.IsKind(SyntaxKind.Interpolation); + } - var root = context.Tree - .GetCompilationUnitRoot(context.CancellationToken); - var leftBraces = root.DescendantTokens() - .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) - && !IsExceptional(t) - && DoesOpenBraceNeedSpace(t)); - var rightBraces = root.DescendantTokens() - .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) - && !IsExceptional(t) - && DoesCloseBraceNeedSpace(t)); - var all = leftBraces.Concat(rightBraces); - foreach (var t in all) - { - context.ReportDiagnostic( - Diagnostic.Create(Rule, t.GetLocation(), t.Text)); - } + var root = context.Tree + .GetCompilationUnitRoot(context.CancellationToken); + var leftBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) + && !IsExceptional(t) + && DoesOpenBraceNeedSpace(t)); + var rightBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) + && !IsExceptional(t) + && DoesCloseBraceNeedSpace(t)); + var all = leftBraces.Concat(rightBraces) + .Select(t => Diagnostic.Create(Rule, t.GetLocation(), t.Text)) + .ToList(); + foreach (var d in all) + { + context.ReportDiagnostic(d); } } } diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs index 3f6b1758..5068350a 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterBrace/CodeFixer.cs @@ -1,59 +1,49 @@ -namespace StyleChecker.Spacing.NoSpaceAfterBrace -{ - using System.Collections.Immutable; - using System.Composition; - using System.Globalization; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.CodeAnalysis; - using Microsoft.CodeAnalysis.CodeActions; - using Microsoft.CodeAnalysis.CodeFixes; - using R = Resources; - - /// - /// NoSpaceAfterBrace code fix provider. - /// - [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixer))] - [Shared] - public sealed class CodeFixer : CodeFixProvider - { - /// - public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); - - /// - public override FixAllProvider GetFixAllProvider() - => WellKnownFixAllProviders.BatchFixer; +namespace StyleChecker.Spacing.NoSpaceAfterBrace; - /// - public override async Task RegisterCodeFixesAsync( - CodeFixContext context) - { - var localize = Localizers.Of(R.ResourceManager); - var title = localize(nameof(R.FixTitle)) - .ToString(CultureInfo.CurrentCulture); +using System.Collections.Immutable; +using System.Composition; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using R = Resources; - var root = await context.Document - .GetSyntaxRootAsync(context.CancellationToken) - .ConfigureAwait(false); - if (root is null) - { - return; - } +/// +/// NoSpaceAfterBrace code fix provider. +/// +[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixer))] +[Shared] +public sealed class CodeFixer : AbstractCodeFixProvider +{ + /// + public override ImmutableArray FixableDiagnosticIds + => [Analyzer.DiagnosticId]; - var diagnostic = context.Diagnostics[0]; - var span = diagnostic.Location.SourceSpan; - var token = root.FindToken(span.Start, findInsideTrivia: true); + /// + public override FixAllProvider GetFixAllProvider() + => WellKnownFixAllProviders.BatchFixer; - Task FixTask(CancellationToken c) - => TokenFix.AddSpaceAfterToken(context.Document, token); + /// + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + var localize = Localizers.Of(R.ResourceManager); + var title = localize(nameof(R.FixTitle)).ToString(CompilerCulture); - context.RegisterCodeFix( - CodeAction.Create( - title: title, - createChangedDocument: FixTask, - equivalenceKey: title), - diagnostic); + var document = context.Document; + if (await document.GetSyntaxRootAsync(context.CancellationToken) + .ConfigureAwait(false) is not {} root) + { + return; } + var diagnostic = context.Diagnostics[0]; + var span = diagnostic.Location.SourceSpan; + var token = root.FindToken(span.Start, findInsideTrivia: true); + var fixTask = TokenFix.NewTask( + () => TokenFix.AddSpaceAfterToken(document, root, token)); + var action = CodeAction.Create( + title: title, + createChangedDocument: fixTask, + equivalenceKey: title); + context.RegisterCodeFix(action, diagnostic); } } diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs index 2d1a7ace..eb723038 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs @@ -1,14 +1,11 @@ namespace StyleChecker.Spacing.NoSpaceAfterSemicolon; -using System; using System.Collections.Immutable; using System.Composition; -using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp; using R = Resources; /// @@ -33,41 +30,21 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var title = localize(nameof(R.FixTitle)) .ToString(CompilerCulture); - if (await context.Document - .GetSyntaxRootAsync(context.CancellationToken) + var document = context.Document; + if (await document.GetSyntaxRootAsync(context.CancellationToken) .ConfigureAwait(false) is not {} root) { return; } - var diagnostic = context.Diagnostics[0]; var span = diagnostic.Location.SourceSpan; var token = root.FindToken(span.Start, findInsideTrivia: true); - - // Task FixTask(CancellationToken c) - // => TokenFix.AddSpaceAfterToken(context.Document, token); - + var fixTask = TokenFix.NewTask( + () => TokenFix.AddSpaceAfterToken(document, root, token)); var action = CodeAction.Create( title: title, - createChangedDocument: Fix(context.Document, root, token), + createChangedDocument: fixTask, equivalenceKey: title); context.RegisterCodeFix(action, diagnostic); } - - private Document FixDocument( - Document document, SyntaxNode root, SyntaxToken token) - { - var list = token.TrailingTrivia; - var space = SyntaxFactory.ParseTrailingTrivia(" "); - var newList = list.InsertRange(0, space); - var newToken = token.WithTrailingTrivia(newList); - var newRoot = root.ReplaceToken(token, newToken); - return document.WithSyntaxRoot(newRoot); - } - - private Func> Fix( - Document document, SyntaxNode root, SyntaxToken token) - { - return c => Task.Run(() => FixDocument(document, root, token), c); - } } diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs index 7dc7d929..9da29554 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/Analyzer.cs @@ -1,123 +1,122 @@ -namespace StyleChecker.Spacing.NoSpaceBeforeBrace -{ - using System; - using System.Collections.Immutable; - using System.Linq; - using Microsoft.CodeAnalysis; - using Microsoft.CodeAnalysis.CSharp; - using Microsoft.CodeAnalysis.Diagnostics; - using R = Resources; +namespace StyleChecker.Spacing.NoSpaceBeforeBrace; + +using System; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Diagnostics; +using R = Resources; +/// +/// NoSpaceBeforeBrace analyzer. +/// +[DiagnosticAnalyzer(LanguageNames.CSharp)] +public sealed class Analyzer : AbstractAnalyzer +{ /// - /// NoSpaceBeforeBrace analyzer. + /// The ID of this analyzer. /// - [DiagnosticAnalyzer(LanguageNames.CSharp)] - public sealed class Analyzer : AbstractAnalyzer - { - /// - /// The ID of this analyzer. - /// - public const string DiagnosticId = "NoSpaceBeforeBrace"; + public const string DiagnosticId = "NoSpaceBeforeBrace"; - private const string Category = Categories.Spacing; - private static readonly DiagnosticDescriptor Rule = NewRule(); + private const string Category = Categories.Spacing; + private static readonly DiagnosticDescriptor Rule = NewRule(); - /// - public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + /// + public override ImmutableArray + SupportedDiagnostics => [Rule]; - /// - private protected override void Register(AnalysisContext context) + /// + private protected override void Register(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.RegisterSyntaxTreeAction(SyntaxTreeAction); + } + + private static DiagnosticDescriptor NewRule() + { + var localize = Localizers.Of(R.ResourceManager); + return new DiagnosticDescriptor( + DiagnosticId, + localize(nameof(R.Title)), + localize(nameof(R.MessageFormat)), + Category, + DiagnosticSeverity.Warning, + isEnabledByDefault: true, + description: localize(nameof(R.Description)), + helpLinkUri: HelpLink.ToUri(DiagnosticId)); + } + + private static void SyntaxTreeAction(SyntaxTreeAnalysisContext context) + { + static bool EndsWithSpace(SyntaxTriviaList list) { - context.EnableConcurrentExecution(); - context.RegisterSyntaxTreeAction(SyntaxTreeAction); + return list.Last() + .IsKindOneOf( + SyntaxKind.WhitespaceTrivia, + SyntaxKind.EndOfLineTrivia); } - private static DiagnosticDescriptor NewRule() + static bool IsOnFirstColumn(SyntaxToken token) { - var localize = Localizers.Of(R.ResourceManager); - return new DiagnosticDescriptor( - DiagnosticId, - localize(nameof(R.Title)), - localize(nameof(R.MessageFormat)), - Category, - DiagnosticSeverity.Warning, - isEnabledByDefault: true, - description: localize(nameof(R.Description)), - helpLinkUri: HelpLink.ToUri(DiagnosticId)); + return token.GetLocation() + .GetLineSpan() + .StartLinePosition + .Character is 0; } - private static void SyntaxTreeAction( - SyntaxTreeAnalysisContext context) + static bool DoesBraceNeedSpace( + SyntaxToken token, Func otherwisePrev) { - static bool EndsWithSpace(SyntaxTriviaList list) - { - return list.Last() - .IsKindOneOf( - SyntaxKind.WhitespaceTrivia, - SyntaxKind.EndOfLineTrivia); - } - - static bool IsOnFirstColumn(SyntaxToken token) - { - return token.GetLocation() - .GetLineSpan() - .StartLinePosition - .Character is 0; - } - - static bool DoesBraceNeedSpace( - SyntaxToken token, Func otherwisePrev) - { - return !IsOnFirstColumn(token) - && token.HasLeadingTrivia - ? !EndsWithSpace(token.LeadingTrivia) - : token.GetPreviousToken() is {} prev - && prev.HasTrailingTrivia - ? !EndsWithSpace(prev.TrailingTrivia) - : otherwisePrev(prev); - } + return !IsOnFirstColumn(token) + && token.HasLeadingTrivia + ? !EndsWithSpace(token.LeadingTrivia) + : token.GetPreviousToken() is {} prev + && prev.HasTrailingTrivia + ? !EndsWithSpace(prev.TrailingTrivia) + : otherwisePrev(prev); + } - static bool DoesOpenBraceNeedSpace(SyntaxToken token) - { - return DoesBraceNeedSpace( - token, - prev => !prev.IsKindOneOf( - SyntaxKind.None, - SyntaxKind.OpenParenToken)); - } + static bool DoesOpenBraceNeedSpace(SyntaxToken token) + { + return DoesBraceNeedSpace( + token, + prev => !prev.IsKindOneOf( + SyntaxKind.None, + SyntaxKind.OpenParenToken)); + } - static bool DoesCloseBraceNeedSpace(SyntaxToken token) - { - return DoesBraceNeedSpace( - token, - prev => !prev.IsKindOneOf( - SyntaxKind.None, - SyntaxKind.OpenBraceToken)); - } + static bool DoesCloseBraceNeedSpace(SyntaxToken token) + { + return DoesBraceNeedSpace( + token, + prev => !prev.IsKindOneOf( + SyntaxKind.None, + SyntaxKind.OpenBraceToken)); + } - static bool IsExceptional(SyntaxToken token) - { - return token.IsMissing - || token.Parent.IsKind(SyntaxKind.Interpolation); - } + static bool IsExceptional(SyntaxToken token) + { + return token.IsMissing + || token.Parent.IsKind(SyntaxKind.Interpolation); + } - var root = context.Tree - .GetCompilationUnitRoot(context.CancellationToken); - var leftBraces = root.DescendantTokens() - .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) - && !IsExceptional(t) - && DoesOpenBraceNeedSpace(t)); - var rightBraces = root.DescendantTokens() - .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) - && !IsExceptional(t) - && DoesCloseBraceNeedSpace(t)); - var all = leftBraces.Concat(rightBraces); - foreach (var t in all) - { - context.ReportDiagnostic( - Diagnostic.Create(Rule, t.GetLocation(), t.Text)); - } + var root = context.Tree + .GetCompilationUnitRoot(context.CancellationToken); + var leftBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.OpenBraceToken) + && !IsExceptional(t) + && DoesOpenBraceNeedSpace(t)); + var rightBraces = root.DescendantTokens() + .Where(t => t.IsKind(SyntaxKind.CloseBraceToken) + && !IsExceptional(t) + && DoesCloseBraceNeedSpace(t)); + var all = leftBraces.Concat(rightBraces) + .Select(t => Diagnostic.Create(Rule, t.GetLocation(), t.Text)) + .ToList(); + foreach (var d in all) + { + context.ReportDiagnostic(d); } } } diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs index 5d272279..60a92404 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceBeforeBrace/CodeFixer.cs @@ -1,59 +1,50 @@ -namespace StyleChecker.Spacing.NoSpaceBeforeBrace -{ - using System.Collections.Immutable; - using System.Composition; - using System.Globalization; - using System.Threading; - using System.Threading.Tasks; - using Microsoft.CodeAnalysis; - using Microsoft.CodeAnalysis.CodeActions; - using Microsoft.CodeAnalysis.CodeFixes; - using R = Resources; - - /// - /// NoSpaceBeforeBrace code fix provider. - /// - [ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixer))] - [Shared] - public sealed class CodeFixer : CodeFixProvider - { - /// - public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); - - /// - public override FixAllProvider GetFixAllProvider() - => WellKnownFixAllProviders.BatchFixer; +namespace StyleChecker.Spacing.NoSpaceBeforeBrace; - /// - public override async Task RegisterCodeFixesAsync( - CodeFixContext context) - { - var localize = Localizers.Of(R.ResourceManager); - var title = localize(nameof(R.FixTitle)) - .ToString(CultureInfo.CurrentCulture); +using System.Collections.Immutable; +using System.Composition; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using R = Resources; - var root = await context.Document - .GetSyntaxRootAsync(context.CancellationToken) - .ConfigureAwait(false); - if (root is null) - { - return; - } +/// +/// NoSpaceBeforeBrace code fix provider. +/// +[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixer))] +[Shared] +public sealed class CodeFixer : AbstractCodeFixProvider +{ + /// + public override ImmutableArray FixableDiagnosticIds + => [Analyzer.DiagnosticId]; - var diagnostic = context.Diagnostics[0]; - var span = diagnostic.Location.SourceSpan; - var token = root.FindToken(span.Start, findInsideTrivia: true); + /// + public override FixAllProvider GetFixAllProvider() + => WellKnownFixAllProviders.BatchFixer; - Task FixTask(CancellationToken c) - => TokenFix.AddSpaceBeforeToken(context.Document, token); + /// + public override async Task RegisterCodeFixesAsync( + CodeFixContext context) + { + var localize = Localizers.Of(R.ResourceManager); + var title = localize(nameof(R.FixTitle)).ToString(CompilerCulture); - context.RegisterCodeFix( - CodeAction.Create( - title: title, - createChangedDocument: FixTask, - equivalenceKey: title), - diagnostic); + var document = context.Document; + if (await document.GetSyntaxRootAsync(context.CancellationToken) + .ConfigureAwait(false) is not {} root) + { + return; } + var diagnostic = context.Diagnostics[0]; + var span = diagnostic.Location.SourceSpan; + var token = root.FindToken(span.Start, findInsideTrivia: true); + var fixTask = TokenFix.NewTask( + () => TokenFix.AddSpaceBeforeToken(document, root, token)); + var action = CodeAction.Create( + title: title, + createChangedDocument: fixTask, + equivalenceKey: title); + context.RegisterCodeFix(action, diagnostic); } } diff --git a/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs index 2b1466e7..628177ba 100644 --- a/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs @@ -1,10 +1,8 @@ namespace StyleChecker.Spacing.SpaceBeforeSemicolon; -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; -using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; @@ -34,21 +32,20 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) var title = localize(nameof(R.FixTitle)) .ToString(CompilerCulture); - var root = await context.Document - .GetSyntaxRootAsync(context.CancellationToken) - .ConfigureAwait(false); - if (root is null) + var document = context.Document; + if (await document.GetSyntaxRootAsync(context.CancellationToken) + .ConfigureAwait(false) is not {} root) { return; } - var diagnostic = context.Diagnostics[0]; var span = diagnostic.Location.SourceSpan; var token = root.FindToken(span.Start, findInsideTrivia: true); - + var fixTask = TokenFix.NewTask( + () => FixDocument(document, root, token)); var action = CodeAction.Create( title: title, - createChangedDocument: Fix(context.Document, root, token), + createChangedDocument: fixTask, equivalenceKey: title); context.RegisterCodeFix(action, diagnostic); } @@ -100,10 +97,4 @@ static SyntaxTriviaList Trim(SyntaxTriviaList triviaList) var newRoot = root.ReplaceTokens(keys, (k, n) => map[k]); return document.WithSyntaxRoot(newRoot); } - - private Func> Fix( - Document document, SyntaxNode root, SyntaxToken token) - { - return c => Task.Run(() => FixDocument(document, root, token), c); - } } diff --git a/StyleChecker/StyleChecker/Spacing/TokenFix.cs b/StyleChecker/StyleChecker/Spacing/TokenFix.cs index fb9bc983..a7d8784e 100644 --- a/StyleChecker/StyleChecker/Spacing/TokenFix.cs +++ b/StyleChecker/StyleChecker/Spacing/TokenFix.cs @@ -1,74 +1,95 @@ -namespace StyleChecker.Spacing +namespace StyleChecker.Spacing; + +using System; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +/// +/// Provides utility methods for fixing tokens. +/// +public static class TokenFix { - using System.Threading.Tasks; - using Microsoft.CodeAnalysis; - using Microsoft.CodeAnalysis.CSharp; + /// + /// Creates a new task that represents the asynchronous operation of fixing + /// tokens in a document. + /// + /// + /// A function that returns the new document after fixing tokens. + /// + /// + /// A task that represents the asynchronous operation of fixing tokens. + /// + public static Func> NewTask( + Func newDocument) + { + return c => Task.Run(newDocument, c); + } /// - /// Provides utility methods for fixing tokens. + /// Gets the new document created by adding a white space immediately after + /// the specified token in the specified document. /// - public static class TokenFix + /// + /// The document containing the . + /// + /// + /// The root node of the syntax tree of the . + /// + /// + /// The token to add a white space after. + /// + /// + /// The new document. + /// + public static Document AddSpaceAfterToken( + Document document, + SyntaxNode root, + SyntaxToken token) { - /// - /// Gets the task that returns a new document created by adding a white - /// space immediately after the specified token in the specified - /// document. - /// - /// - /// The document containing the . - /// - /// - /// The token to add a white space after. - /// - /// - /// The new document. - /// - public static Task AddSpaceAfterToken( - Document document, - SyntaxToken token) - { - var list = token.TrailingTrivia; - var space = SyntaxFactory.ParseTrailingTrivia(" "); - var newList = list.InsertRange(0, space); - var newToken = token.WithTrailingTrivia(newList); - return Replace(document, token, newToken); - } + var list = token.TrailingTrivia; + var space = SyntaxFactory.ParseTrailingTrivia(" "); + var newList = list.InsertRange(0, space); + var newToken = token.WithTrailingTrivia(newList); + return Replace(document, root, token, newToken); + } - /// - /// Gets the task that returns a new document created by adding a white - /// space immediately before the specified token in the specified - /// document. - /// - /// - /// The document containing the . - /// - /// - /// The token to add a white space before. - /// - /// - /// The new document. - /// - public static Task AddSpaceBeforeToken( - Document document, - SyntaxToken token) - { - var list = token.LeadingTrivia; - var space = SyntaxFactory.ParseLeadingTrivia(" "); - var newList = list.AddRange(space); - var newToken = token.WithLeadingTrivia(newList); - return Replace(document, token, newToken); - } + /// + /// Gets the new document created by adding a white space immediately + /// before the specified token in the specified document. + /// + /// + /// The document containing the . + /// + /// + /// The root node of the syntax tree of the . + /// + /// + /// The token to add a white space before. + /// + /// + /// The new document. + /// + public static Document AddSpaceBeforeToken( + Document document, + SyntaxNode root, + SyntaxToken token) + { + var list = token.LeadingTrivia; + var space = SyntaxFactory.ParseLeadingTrivia(" "); + var newList = list.AddRange(space); + var newToken = token.WithLeadingTrivia(newList); + return Replace(document, root, token, newToken); + } - private static async Task Replace( - Document document, - SyntaxToken token, - SyntaxToken newToken) - { - var root = token.SyntaxTree - .GetRoot(); - var newRoot = root.ReplaceToken(token, newToken); - return await Task.Run(() => document.WithSyntaxRoot(newRoot)) - .ConfigureAwait(false); - } + private static Document Replace( + Document document, + SyntaxNode root, + SyntaxToken token, + SyntaxToken newToken) + { + var newRoot = root.ReplaceToken(token, newToken); + return document.WithSyntaxRoot(newRoot); } } From 2d95327249e8ff749aff7b0805543a74ecd58318 Mon Sep 17 00:00:00 2001 From: Tomohisa Tanaka Date: Tue, 7 May 2024 22:05:42 +0900 Subject: [PATCH 5/6] Refactor - Fix warnings - Use more collection expressions --- .../Framework/BeliefsTests.cs | 2 +- .../Cleaning/ByteOrderMark/Analyzer.cs | 2 +- .../Cleaning/ByteOrderMark/BomKit.cs | 2 +- .../Cleaning/ByteOrderMark/Globs.cs | 20 ++++--------------- .../RedundantTypedArrayCreation/Analyzer.cs | 2 +- .../RedundantTypedArrayCreation/CodeFixer.cs | 2 +- .../Cleaning/UnusedUsing/Analyzer.cs | 2 +- .../Cleaning/UnusedVariable/Analyzer.cs | 2 +- .../Document/NoDocumentation/Analyzer.cs | 2 +- .../Document/StrayText/Analyzer.cs | 2 +- .../Naming/SingleTypeParameter/Analyzer.cs | 2 +- .../Naming/SingleTypeParameter/CodeFixer.cs | 2 +- .../Naming/ThoughtlessName/Analyzer.cs | 10 +++++----- .../Naming/Underscore/Analyzer.cs | 3 +-- .../Naming/Underscore/CodeFixer.cs | 2 +- .../Ordering/PostIncrement/Analyzer.cs | 2 +- .../Ordering/PostIncrement/CodeFixer.cs | 2 +- .../AssignmentToParameter/Analyzer.cs | 2 +- .../DiscardingReturnValue/Analyzer.cs | 2 +- .../EmptyArrayCreation/Analyzer.cs | 2 +- .../EmptyArrayCreation/CodeFixer.cs | 2 +- .../EqualsNull/AbstractCodeFixer.cs | 2 +- .../Refactoring/EqualsNull/Analyzer.cs | 2 +- .../EqualsNull/IsBracesCodeFixer.cs | 15 +++++++------- .../Refactoring/EqualsNull/IsNullCodeFixer.cs | 15 +++++++------- .../IneffectiveReadByte/Analyzer.cs | 2 +- .../IneffectiveReadByte/CodeFixer.cs | 2 +- .../Refactoring/IsNull/AbstractCodeFixer.cs | 2 +- .../Refactoring/IsNull/Analyzer.cs | 2 +- .../Refactoring/IsNull/EqualNullCodeFixer.cs | 13 ++++++------ .../Refactoring/IsNull/IsBracesCodeFixer.cs | 11 +++++----- .../NotDesignedForExtension/Analyzer.cs | 2 +- .../NotOneShotInitialization/Analyzer.cs | 4 ++-- .../StaticGenericClass/Analyzer.cs | 2 +- .../StaticGenericClass/CodeFixer.cs | 2 +- .../StinkyBooleanExpression/Analyzer.cs | 6 +++--- .../StinkyBooleanExpression/CodeFixer.cs | 2 +- .../TypeClassParameter/Analyzer.cs | 2 +- .../TypeClassParameter/CodeFixer.cs | 2 +- .../UninitializedLocalVariable/Analyzer.cs | 2 +- .../Refactoring/UnnecessaryUsing/Analyzer.cs | 15 +------------- .../Refactoring/UnnecessaryUsing/Classes.cs | 15 +++++++------- .../Refactoring/UnnecessaryUsing/CodeFixer.cs | 2 +- .../Settings/InvalidConfig/Analyzer.cs | 2 +- .../StyleChecker/Size/LongLine/Analyzer.cs | 2 +- .../NoSingleSpaceAfterTripleSlash/Analyzer.cs | 4 ++-- .../CodeFixer.cs | 2 +- .../Spacing/NoSpaceAfterSemicolon/Analyzer.cs | 2 +- .../NoSpaceAfterSemicolon/CodeFixer.cs | 2 +- .../Spacing/SpaceBeforeSemicolon/Analyzer.cs | 2 +- .../Spacing/SpaceBeforeSemicolon/CodeFixer.cs | 2 +- 51 files changed, 89 insertions(+), 120 deletions(-) diff --git a/StyleChecker/StyleChecker.Test/Framework/BeliefsTests.cs b/StyleChecker/StyleChecker.Test/Framework/BeliefsTests.cs index 6c38d42b..21e5beee 100644 --- a/StyleChecker/StyleChecker.Test/Framework/BeliefsTests.cs +++ b/StyleChecker/StyleChecker.Test/Framework/BeliefsTests.cs @@ -382,7 +382,7 @@ static Result ToResult(Belief b) Assert.AreEqual(3, firstResult.Locations[0].Line); } - private void ExpectCompilationException(string encodedSource) + private static void ExpectCompilationException(string encodedSource) { static Result ToResult(Belief b) => b.ToResult("TestId", b.Message); diff --git a/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Analyzer.cs b/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Analyzer.cs index 0a938742..d1e5d017 100644 --- a/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Analyzer.cs +++ b/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Analyzer.cs @@ -30,7 +30,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/BomKit.cs b/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/BomKit.cs index a7b9dc2a..c760479c 100644 --- a/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/BomKit.cs +++ b/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/BomKit.cs @@ -11,7 +11,7 @@ namespace StyleChecker.Cleaning.ByteOrderMark; public static class BomKit { private static readonly ImmutableArray Utf8ByteOrderMark - = ImmutableArray.Create(0xef, 0xbb, 0xbf); + = [0xef, 0xbb, 0xbf]; /// /// Gets whether the file of the specified path starts with UTF-8 BOM. diff --git a/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Globs.cs b/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Globs.cs index d0207186..8c1940a9 100644 --- a/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Globs.cs +++ b/StyleChecker/StyleChecker/Cleaning/ByteOrderMark/Globs.cs @@ -17,22 +17,10 @@ public static class Globs private static readonly Regex SlashSequencePattern = new("//+"); - private static readonly ImmutableHashSet NeedsEscapeCharSet - = ImmutableHashSet.Create( - '\\', - '[', - ']', - '.', - '*', - '+', - '?', - '^', - '$', - '(', - ')', - '{', - '}', - '|'); + private static readonly ImmutableHashSet NeedsEscapeCharSet = [ + '\\', '[', ']', '.', '*', '+', '?', '^', '$', '(', ')', '{', '}', + '|', + ]; private static readonly Action DoNothing = () => {}; diff --git a/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/Analyzer.cs b/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/Analyzer.cs index fe40e5d0..d0343108 100644 --- a/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/Analyzer.cs +++ b/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/Analyzer.cs @@ -29,7 +29,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/CodeFixer.cs b/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/CodeFixer.cs index 8c2c9218..cecbbcee 100644 --- a/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Cleaning/RedundantTypedArrayCreation/CodeFixer.cs @@ -22,7 +22,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Cleaning/UnusedUsing/Analyzer.cs b/StyleChecker/StyleChecker/Cleaning/UnusedUsing/Analyzer.cs index 20e47271..59c8bf21 100644 --- a/StyleChecker/StyleChecker/Cleaning/UnusedUsing/Analyzer.cs +++ b/StyleChecker/StyleChecker/Cleaning/UnusedUsing/Analyzer.cs @@ -22,7 +22,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Cleaning/UnusedVariable/Analyzer.cs b/StyleChecker/StyleChecker/Cleaning/UnusedVariable/Analyzer.cs index d0c27744..a9ff47d8 100644 --- a/StyleChecker/StyleChecker/Cleaning/UnusedVariable/Analyzer.cs +++ b/StyleChecker/StyleChecker/Cleaning/UnusedVariable/Analyzer.cs @@ -30,7 +30,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Document/NoDocumentation/Analyzer.cs b/StyleChecker/StyleChecker/Document/NoDocumentation/Analyzer.cs index 47e73024..889300a0 100644 --- a/StyleChecker/StyleChecker/Document/NoDocumentation/Analyzer.cs +++ b/StyleChecker/StyleChecker/Document/NoDocumentation/Analyzer.cs @@ -35,7 +35,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Document/StrayText/Analyzer.cs b/StyleChecker/StyleChecker/Document/StrayText/Analyzer.cs index 8d26f259..57dd580f 100644 --- a/StyleChecker/StyleChecker/Document/StrayText/Analyzer.cs +++ b/StyleChecker/StyleChecker/Document/StrayText/Analyzer.cs @@ -25,7 +25,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Naming/SingleTypeParameter/Analyzer.cs b/StyleChecker/StyleChecker/Naming/SingleTypeParameter/Analyzer.cs index 71ecae74..7e3a27b4 100644 --- a/StyleChecker/StyleChecker/Naming/SingleTypeParameter/Analyzer.cs +++ b/StyleChecker/StyleChecker/Naming/SingleTypeParameter/Analyzer.cs @@ -25,7 +25,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Naming/SingleTypeParameter/CodeFixer.cs b/StyleChecker/StyleChecker/Naming/SingleTypeParameter/CodeFixer.cs index a4c4e3dc..e2937bc1 100644 --- a/StyleChecker/StyleChecker/Naming/SingleTypeParameter/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Naming/SingleTypeParameter/CodeFixer.cs @@ -20,7 +20,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Naming/ThoughtlessName/Analyzer.cs b/StyleChecker/StyleChecker/Naming/ThoughtlessName/Analyzer.cs index 52a104e8..cb7308c7 100644 --- a/StyleChecker/StyleChecker/Naming/ThoughtlessName/Analyzer.cs +++ b/StyleChecker/StyleChecker/Naming/ThoughtlessName/Analyzer.cs @@ -28,7 +28,7 @@ public sealed class Analyzer : AbstractAnalyzer private static readonly DiagnosticDescriptor Rule = NewRule(); private static readonly ImmutableHashSet - SinglePrefixTypeSet = ImmutableHashSet.Create( + SinglePrefixTypeSet = [ SpecialType.System_Boolean, SpecialType.System_Byte, SpecialType.System_Int16, @@ -39,14 +39,14 @@ private static readonly ImmutableHashSet SpecialType.System_Double, SpecialType.System_Object, SpecialType.System_String, - SpecialType.System_Decimal); + SpecialType.System_Decimal]; private static readonly ImmutableHashSet - DoublePrefixTypeSet = ImmutableHashSet.Create( + DoublePrefixTypeSet = [ SpecialType.System_SByte, SpecialType.System_UInt16, SpecialType.System_UInt32, - SpecialType.System_UInt64); + SpecialType.System_UInt64]; private static readonly IReadOnlyDictionary SpecialTypeNameMap = new Dictionary() @@ -70,7 +70,7 @@ private static readonly IReadOnlyDictionary /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Naming/Underscore/Analyzer.cs b/StyleChecker/StyleChecker/Naming/Underscore/Analyzer.cs index a4707513..f2b3b093 100644 --- a/StyleChecker/StyleChecker/Naming/Underscore/Analyzer.cs +++ b/StyleChecker/StyleChecker/Naming/Underscore/Analyzer.cs @@ -25,8 +25,7 @@ private static readonly DiagnosticDescriptor IncludeRule /// public override ImmutableArray - SupportedDiagnostics - => ImmutableArray.Create(IncludeRule, IsRule); + SupportedDiagnostics => [IncludeRule, IsRule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Naming/Underscore/CodeFixer.cs b/StyleChecker/StyleChecker/Naming/Underscore/CodeFixer.cs index 74c36429..bbb02dfb 100644 --- a/StyleChecker/StyleChecker/Naming/Underscore/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Naming/Underscore/CodeFixer.cs @@ -24,7 +24,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Ordering/PostIncrement/Analyzer.cs b/StyleChecker/StyleChecker/Ordering/PostIncrement/Analyzer.cs index bb62d23e..d1b86922 100644 --- a/StyleChecker/StyleChecker/Ordering/PostIncrement/Analyzer.cs +++ b/StyleChecker/StyleChecker/Ordering/PostIncrement/Analyzer.cs @@ -25,7 +25,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Ordering/PostIncrement/CodeFixer.cs b/StyleChecker/StyleChecker/Ordering/PostIncrement/CodeFixer.cs index 6dfac7e8..de8e6f05 100644 --- a/StyleChecker/StyleChecker/Ordering/PostIncrement/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Ordering/PostIncrement/CodeFixer.cs @@ -26,7 +26,7 @@ private static readonly Func KindMap /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Refactoring/AssignmentToParameter/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/AssignmentToParameter/Analyzer.cs index 819a5a4f..f197ef9c 100644 --- a/StyleChecker/StyleChecker/Refactoring/AssignmentToParameter/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/AssignmentToParameter/Analyzer.cs @@ -26,7 +26,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/DiscardingReturnValue/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/DiscardingReturnValue/Analyzer.cs index 1a5ee1bf..efdf9c48 100644 --- a/StyleChecker/StyleChecker/Refactoring/DiscardingReturnValue/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/DiscardingReturnValue/Analyzer.cs @@ -57,7 +57,7 @@ private static readonly SymbolDisplayFormat SignatureFormat /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/Analyzer.cs index f737a0c9..62025aee 100644 --- a/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/Analyzer.cs @@ -26,7 +26,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/CodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/CodeFixer.cs index abc8519c..3b7c8cfd 100644 --- a/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/EmptyArrayCreation/CodeFixer.cs @@ -22,7 +22,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Refactoring/EqualsNull/AbstractCodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/EqualsNull/AbstractCodeFixer.cs index dac15c5a..6bca1581 100644 --- a/StyleChecker/StyleChecker/Refactoring/EqualsNull/AbstractCodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/EqualsNull/AbstractCodeFixer.cs @@ -16,7 +16,7 @@ public abstract class AbstractCodeFixer : AbstractRevisingCodeFixer { /// public sealed override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// protected sealed override Func Localize diff --git a/StyleChecker/StyleChecker/Refactoring/EqualsNull/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/EqualsNull/Analyzer.cs index 21f8f9ed..5d4b3909 100644 --- a/StyleChecker/StyleChecker/Refactoring/EqualsNull/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/EqualsNull/Analyzer.cs @@ -26,7 +26,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsBracesCodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsBracesCodeFixer.cs index 56e8b4a6..759a3d55 100644 --- a/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsBracesCodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsBracesCodeFixer.cs @@ -15,14 +15,13 @@ namespace StyleChecker.Refactoring.EqualsNull; [Shared] public sealed class IsBracesCodeFixer : AbstractCodeFixer { - private static readonly ImmutableList KitList - = ImmutableList.Create( - new ReviserKit( - nameof(R.FixTitleIsBraces), - Replace(SyntaxKind.ExclamationEqualsToken, NotEqual)), - new ReviserKit( - nameof(R.FixTitleIsNotBraces), - Replace(SyntaxKind.EqualsEqualsToken, EqualEqual))); + private static readonly ImmutableList KitList = [ + new ReviserKit( + nameof(R.FixTitleIsBraces), + Replace(SyntaxKind.ExclamationEqualsToken, NotEqual)), + new ReviserKit( + nameof(R.FixTitleIsNotBraces), + Replace(SyntaxKind.EqualsEqualsToken, EqualEqual))]; /// protected override ImmutableList ReviserKitList => KitList; diff --git a/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsNullCodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsNullCodeFixer.cs index f6ac4149..52b96ce4 100644 --- a/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsNullCodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/EqualsNull/IsNullCodeFixer.cs @@ -15,14 +15,13 @@ namespace StyleChecker.Refactoring.EqualsNull; [Shared] public sealed class IsNullCodeFixer : AbstractCodeFixer { - private static readonly ImmutableList KitList - = ImmutableList.Create( - new ReviserKit( - nameof(R.FixTitleIsNotNull), - Replace(SyntaxKind.EqualsEqualsToken, NotEqual)), - new ReviserKit( - nameof(R.FixTitleIsNull), - Replace(SyntaxKind.ExclamationEqualsToken, EqualEqual))); + private static readonly ImmutableList KitList = [ + new ReviserKit( + nameof(R.FixTitleIsNotNull), + Replace(SyntaxKind.EqualsEqualsToken, NotEqual)), + new ReviserKit( + nameof(R.FixTitleIsNull), + Replace(SyntaxKind.ExclamationEqualsToken, EqualEqual))]; /// protected override ImmutableList ReviserKitList => KitList; diff --git a/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/Analyzer.cs index b48864a1..1efc14fa 100644 --- a/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/Analyzer.cs @@ -27,7 +27,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/CodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/CodeFixer.cs index 6902560c..a87e5a9a 100644 --- a/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/IneffectiveReadByte/CodeFixer.cs @@ -22,7 +22,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Refactoring/IsNull/AbstractCodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/IsNull/AbstractCodeFixer.cs index b888aacf..3e9bcea0 100644 --- a/StyleChecker/StyleChecker/Refactoring/IsNull/AbstractCodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/IsNull/AbstractCodeFixer.cs @@ -14,7 +14,7 @@ public abstract class AbstractCodeFixer : AbstractRevisingCodeFixer { /// public sealed override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// protected sealed override Func Localize diff --git a/StyleChecker/StyleChecker/Refactoring/IsNull/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/IsNull/Analyzer.cs index 53607c08..a2bc93a3 100644 --- a/StyleChecker/StyleChecker/Refactoring/IsNull/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/IsNull/Analyzer.cs @@ -26,7 +26,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/IsNull/EqualNullCodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/IsNull/EqualNullCodeFixer.cs index 88737f8e..d686f494 100644 --- a/StyleChecker/StyleChecker/Refactoring/IsNull/EqualNullCodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/IsNull/EqualNullCodeFixer.cs @@ -19,13 +19,12 @@ namespace StyleChecker.Refactoring.IsNull; [Shared] public sealed class EqualNullCodeFixer : AbstractCodeFixer { - private static readonly ImmutableList KitList - = ImmutableList.Create( - new ReviserKit( - nameof(R.FixTitleEqualNull), ReplaceIsNullWithEqualOperator), - new ReviserKit( - nameof(R.FixTitleNotEqualNull), - ReplaceNotIsNullWithNotEqualOperator)); + private static readonly ImmutableList KitList = [ + new ReviserKit( + nameof(R.FixTitleEqualNull), ReplaceIsNullWithEqualOperator), + new ReviserKit( + nameof(R.FixTitleNotEqualNull), + ReplaceNotIsNullWithNotEqualOperator)]; /// protected override ImmutableList ReviserKitList => KitList; diff --git a/StyleChecker/StyleChecker/Refactoring/IsNull/IsBracesCodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/IsNull/IsBracesCodeFixer.cs index 01be3bde..44601973 100644 --- a/StyleChecker/StyleChecker/Refactoring/IsNull/IsBracesCodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/IsNull/IsBracesCodeFixer.cs @@ -18,12 +18,11 @@ namespace StyleChecker.Refactoring.IsNull; [Shared] public sealed class IsBracesCodeFixer : AbstractCodeFixer { - private static readonly ImmutableList KitList - = ImmutableList.Create( - new ReviserKit( - nameof(R.FixTitleIsBraces), ReplaceIsNullWithNotIsBraces), - new ReviserKit( - nameof(R.FixTitleNotIsBraces), ReplaceNotIsNullWithIsBraces)); + private static readonly ImmutableList KitList = [ + new ReviserKit( + nameof(R.FixTitleIsBraces), ReplaceIsNullWithNotIsBraces), + new ReviserKit( + nameof(R.FixTitleNotIsBraces), ReplaceNotIsNullWithIsBraces)]; /// protected override ImmutableList ReviserKitList => KitList; diff --git a/StyleChecker/StyleChecker/Refactoring/NotDesignedForExtension/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/NotDesignedForExtension/Analyzer.cs index 3f6939ee..54696423 100644 --- a/StyleChecker/StyleChecker/Refactoring/NotDesignedForExtension/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/NotDesignedForExtension/Analyzer.cs @@ -26,7 +26,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/NotOneShotInitialization/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/NotOneShotInitialization/Analyzer.cs index 1a0557ba..aead281f 100644 --- a/StyleChecker/StyleChecker/Refactoring/NotOneShotInitialization/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/NotOneShotInitialization/Analyzer.cs @@ -30,14 +30,14 @@ public sealed class Analyzer : AbstractAnalyzer private static readonly DiagnosticDescriptor Rule = NewRule(); private static readonly ImmutableHashSet - NoLocalSymbols = ImmutableHashSet.Empty; + NoLocalSymbols = []; private static readonly IEnumerable<(ILocalSymbol, SyntaxToken)> EmptyLocalSymbolTokens = []; /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/Analyzer.cs index 70f024c3..96212d5d 100644 --- a/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/Analyzer.cs @@ -27,7 +27,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/CodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/CodeFixer.cs index bfb4cb70..e07a6dc2 100644 --- a/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/StaticGenericClass/CodeFixer.cs @@ -60,7 +60,7 @@ private delegate SyntaxTriviaList CommentKit( /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/Analyzer.cs index 2b05c360..102dc925 100644 --- a/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/Analyzer.cs @@ -26,12 +26,12 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; private static ImmutableHashSet - BoolLiteralExpressionSet { get; } = ImmutableHashSet.Create( + BoolLiteralExpressionSet { get; } = [ SyntaxKind.TrueLiteralExpression, - SyntaxKind.FalseLiteralExpression); + SyntaxKind.FalseLiteralExpression]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/CodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/CodeFixer.cs index 197152b1..e8e4b9df 100644 --- a/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/StinkyBooleanExpression/CodeFixer.cs @@ -22,7 +22,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/Analyzer.cs index 6bd63ceb..e222eb50 100644 --- a/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/Analyzer.cs @@ -28,7 +28,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/CodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/CodeFixer.cs index 50dce611..bc4dbdeb 100644 --- a/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/TypeClassParameter/CodeFixer.cs @@ -35,7 +35,7 @@ private static readonly Func /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Refactoring/UninitializedLocalVariable/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/UninitializedLocalVariable/Analyzer.cs index c7ae829b..ba5d0107 100644 --- a/StyleChecker/StyleChecker/Refactoring/UninitializedLocalVariable/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/UninitializedLocalVariable/Analyzer.cs @@ -23,7 +23,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs index 04ff805b..1afd5dcc 100644 --- a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs @@ -29,7 +29,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) @@ -52,19 +52,6 @@ private static DiagnosticDescriptor NewRule() helpLinkUri: HelpLink.ToUri(DiagnosticId)); } - private static Func NewDisposesNothing() - { - var classSet = new HashSet() - { - typeof(MemoryStream).FullName, - typeof(StringReader).FullName, - typeof(StringWriter).FullName, - "System.IO.UnmanagedMemoryAccessor", - "System.IO.UnmanagedMemoryStream", - }; - return classSet.Contains; - } - private static void AnalyzeModel( SemanticModelAnalysisContext context) { diff --git a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Classes.cs b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Classes.cs index 5ad89139..b3f62683 100644 --- a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Classes.cs +++ b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Classes.cs @@ -24,12 +24,11 @@ public static class Classes public static bool DisposesNothing(string className) => ClassNameSet.Contains(className); - private static ImmutableHashSet NewClassNameSet() - => ImmutableHashSet.Create([ - typeof(MemoryStream).FullName, - typeof(StringReader).FullName, - typeof(StringWriter).FullName, - "System.IO.UnmanagedMemoryAccessor", - "System.IO.UnmanagedMemoryStream", - ]); + private static ImmutableHashSet NewClassNameSet() => [ + typeof(MemoryStream).FullName, + typeof(StringReader).FullName, + typeof(StringWriter).FullName, + "System.IO.UnmanagedMemoryAccessor", + "System.IO.UnmanagedMemoryStream", + ]; } diff --git a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/CodeFixer.cs b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/CodeFixer.cs index 364c1971..9eb649df 100644 --- a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/CodeFixer.cs @@ -24,7 +24,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Settings/InvalidConfig/Analyzer.cs b/StyleChecker/StyleChecker/Settings/InvalidConfig/Analyzer.cs index e353dd9b..388e8875 100644 --- a/StyleChecker/StyleChecker/Settings/InvalidConfig/Analyzer.cs +++ b/StyleChecker/StyleChecker/Settings/InvalidConfig/Analyzer.cs @@ -27,7 +27,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Size/LongLine/Analyzer.cs b/StyleChecker/StyleChecker/Size/LongLine/Analyzer.cs index 761963ad..bdd2490e 100644 --- a/StyleChecker/StyleChecker/Size/LongLine/Analyzer.cs +++ b/StyleChecker/StyleChecker/Size/LongLine/Analyzer.cs @@ -24,7 +24,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/Analyzer.cs index deba9959..bbe61a73 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/Analyzer.cs @@ -25,11 +25,11 @@ public const string DiagnosticId private static readonly DiagnosticDescriptor Rule = NewRule(); private static readonly ImmutableHashSet WhitespaceCharSet - = ImmutableHashSet.Create(' ', '\t'); + = [' ', '\t']; /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/CodeFixer.cs index e073c7b7..02bd9829 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSingleSpaceAfterTripleSlash/CodeFixer.cs @@ -21,7 +21,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/Analyzer.cs index 5253797d..35a71b33 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/Analyzer.cs @@ -23,7 +23,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs index eb723038..b846242a 100644 --- a/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/NoSpaceAfterSemicolon/CodeFixer.cs @@ -17,7 +17,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() diff --git a/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/Analyzer.cs b/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/Analyzer.cs index c22b25b2..c1587465 100644 --- a/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/Analyzer.cs +++ b/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/Analyzer.cs @@ -23,7 +23,7 @@ public sealed class Analyzer : AbstractAnalyzer /// public override ImmutableArray - SupportedDiagnostics => ImmutableArray.Create(Rule); + SupportedDiagnostics => [Rule]; /// private protected override void Register(AnalysisContext context) diff --git a/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs b/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs index 628177ba..eed2556f 100644 --- a/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs +++ b/StyleChecker/StyleChecker/Spacing/SpaceBeforeSemicolon/CodeFixer.cs @@ -19,7 +19,7 @@ public sealed class CodeFixer : AbstractCodeFixProvider { /// public override ImmutableArray FixableDiagnosticIds - => ImmutableArray.Create(Analyzer.DiagnosticId); + => [Analyzer.DiagnosticId]; /// public override FixAllProvider GetFixAllProvider() From 6a17b92f7f444bca7aece37a7329b5c0154bdf68 Mon Sep 17 00:00:00 2001 From: Tomohisa Tanaka Date: Tue, 7 May 2024 22:20:29 +0900 Subject: [PATCH 6/6] Fix warnings --- .../StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs index 1afd5dcc..4999e77d 100644 --- a/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs +++ b/StyleChecker/StyleChecker/Refactoring/UnnecessaryUsing/Analyzer.cs @@ -3,7 +3,6 @@ namespace StyleChecker.Refactoring.UnnecessaryUsing; using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.IO; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp;