Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
d8d8193
Added ignoring of JetBrains Rider/Idea files
AndreiShenets Mar 30, 2025
3afb7e8
Added forcing of 2 space indent for Analyzers.xml files. Disabled tri…
AndreiShenets Mar 30, 2025
acc6303
Generated constants for RCS1269
AndreiShenets Mar 30, 2025
48719da
Adjusted indent size for *.xml files
AndreiShenets Mar 30, 2025
be55b98
Added TargetBracesStyle
AndreiShenets Mar 30, 2025
8e7c264
Implementing
AndreiShenets Mar 30, 2025
dc86f5f
Implementing
AndreiShenets Apr 6, 2025
bcdeff0
Implementing
AndreiShenets Apr 11, 2025
308625b
Fixed analyzer description
AndreiShenets Apr 11, 2025
683523f
Cleanup
AndreiShenets Apr 11, 2025
1e6a8dd
Fixed tests. Added missed cancellation tokens
AndreiShenets Apr 12, 2025
ed88447
Added missed license headers
AndreiShenets Apr 21, 2025
b4a3c9c
Declared new analyzer and formatter
AndreiShenets Apr 21, 2025
e1b4987
Added test description
AndreiShenets Apr 21, 2025
d2dd013
Analyzer created from copy
AndreiShenets Apr 21, 2025
f64ddc1
Merge remote-tracking branch 'origin/main' into 1636-new_analyzers
AndreiShenets May 1, 2025
5e618f7
Potential fix for the build
AndreiShenets May 1, 2025
040a7a6
Potential fix for the build
AndreiShenets May 2, 2025
8d5fe0c
Implementing
AndreiShenets May 3, 2025
65480de
Implementing
AndreiShenets May 3, 2025
2fd3896
Added additional tests
AndreiShenets May 3, 2025
df09b01
Implemented fixer
AndreiShenets May 4, 2025
1eaae70
Added additional test. Added license information in the header
AndreiShenets May 4, 2025
ba38e5e
RS1024,RS1025,RS1026 removed from treating as Errors during the build
AndreiShenets May 16, 2025
6433046
Fixed broken .editorconfig
AndreiShenets May 25, 2025
db5d274
Reverted introducing of RS1024,RS1025,RS1026 in the build pipeline
AndreiShenets May 25, 2025
5180947
Fixed bitwise warning
AndreiShenets May 25, 2025
9cd4e7a
Fixed bitwise warning
AndreiShenets May 25, 2025
6e315e3
Applied dotnet format Roslynator.sln --severity info
AndreiShenets May 25, 2025
6ffaf60
Fixed use specific type formatting issue
AndreiShenets May 25, 2025
73f2724
Fixed typo complains from the build
AndreiShenets May 29, 2025
da052e0
SyntaxKind.CollectionExpression excluded for earlier Roslyn versions
AndreiShenets May 29, 2025
5d417fa
Updated change log
AndreiShenets May 29, 2025
b102a30
Added potential fix for the build
AndreiShenets May 29, 2025
d16da29
CollectionExpressionSyntax excluded for earlier Roslyn versions
AndreiShenets Jun 3, 2025
8257bad
A try to fix the build
AndreiShenets Jun 8, 2025
12e5211
Revert "A try to fix the build"
AndreiShenets Jun 25, 2025
d4c06c1
Updated .net version for the installation
AndreiShenets Jun 25, 2025
43bcc08
Merge branch '1636-new_analyzers' into 1636-new-alalyzers-2
AndreiShenets Jul 5, 2025
1baac2e
Fixing formatting
AndreiShenets Jul 5, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ root = true
[*]
indent_style = space

[*.xml]
indent_size = 2

[Analyzers.xml]
trim_trailing_whitespace = false

# Code files
[*.{cs,csx}]
indent_size = 4
Expand Down
17 changes: 10 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ jobs:
../wordb/data/tech.acronyms.txt

build_core_and_testing:
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
needs: pre_build
runs-on: ubuntu-24.04
env:
Expand All @@ -90,7 +90,7 @@ jobs:
path: src/_nupkg/*nupkg

build_analyzers:
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
needs: pre_build
runs-on: ubuntu-24.04
env:
Expand Down Expand Up @@ -123,7 +123,7 @@ jobs:
path: src/${{ matrix.component.name }}.CodeFixes/bin/Release/*.*nupkg

build_refactorings:
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
needs: pre_build
runs-on: ubuntu-24.04
env:
Expand All @@ -144,7 +144,7 @@ jobs:
path: src/Refactorings/bin/Release/*.*nupkg

build_code_fixes:
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
needs: pre_build
runs-on: ubuntu-24.04
env:
Expand All @@ -165,7 +165,7 @@ jobs:
path: src/CodeFixes/bin/Release/*.*nupkg

build_vs_extension:
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
needs: pre_build
runs-on: windows-latest
env:
Expand Down Expand Up @@ -199,7 +199,7 @@ jobs:
delete-merged: true

build_vs_code_extension:
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
if: github.ref_type != 'tag' || startsWith(github.ref_name, 'v')
needs: [ pre_build, build_analyzers ]
runs-on: ubuntu-24.04
env:
Expand All @@ -209,6 +209,9 @@ jobs:
working-directory: src/VisualStudioCode
steps:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.301
- run: dotnet restore
- run: dotnet build --no-restore
- run: |
Expand Down Expand Up @@ -263,7 +266,7 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-dotnet@v4
with:
dotnet-version: 9.0.101
dotnet-version: 9.0.301
- run: dotnet restore
- run: dotnet build --no-restore
- run: dotnet pack --no-build
Expand Down
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ publish/
*.[Pp]ublish.xml
*.azurePubxml

# TODO: Un-comment the next line if you do not want to checkin
# TODO: Un-comment the next line if you do not want to checkin
# your web deploy settings because they may include unencrypted
# passwords
#*.pubxml
Expand Down Expand Up @@ -244,4 +244,7 @@ ModelManifest.xml
# FAKE - F# Make
.fake/

.DS_Store
.DS_Store

# JetBrains Rider setting files
.idea/
74 changes: 74 additions & 0 deletions src/Analyzers.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7819,6 +7819,80 @@ string s = """
</Sample>
</Samples>
</Analyzer>
<Analyzer>
<Id>RCS1269</Id>
<Identifier>FixBracketFormattingOfList</Identifier>
<Title>Fix bracket formatting of a list</Title>
<MessageFormat>Fix bracket formatting of {0}</MessageFormat>
<DefaultSeverity>Info</DefaultSeverity>
<IsEnabledByDefault>false</IsEnabledByDefault>
<ConfigOptions>
<Option Key="target_braces_style" />
</ConfigOptions>
<Summary>
This analyzer:
* adds new line after an opening bracket of argument/parameter lists and similar lists
* adds new line before a closing bracket of argument/parameter lists and similar lists
* aligns the closing bracket with the block containing its opening bracket
The analyzer works only for multi-line declarations.
</Summary>
<Samples>
<Sample>
<Before><![CDATA[void M(object x,
object y)
{
}]]></Before>
<After><![CDATA[void M(
object x,
object y
)
{
}]]></After>
</Sample>
<Sample>
<Before><![CDATA[Method(xParameter,
yParameter);]]></Before>
<After><![CDATA[Method(
xParameter,
yParameter
);]]></After>
</Sample>
</Samples>
</Analyzer>
<Analyzer>
<Id>RCS1270</Id>
<Identifier>FixBracketFormattingOfBinaryExpression</Identifier>
<Title>Fix bracket formatting of a binary expression</Title>
<MessageFormat>Fix bracket formatting of {0}</MessageFormat>
<DefaultSeverity>Info</DefaultSeverity>
<IsEnabledByDefault>false</IsEnabledByDefault>
<ConfigOptions>
<Option Key="target_braces_style" />
</ConfigOptions>
<Summary>
This analyzer:
* adds new line after an opening bracket of binary expressions
* adds new line before a closing bracket of binary expressions
* aligns the closing bracket with the block containing its opening bracket
The analyzer works only for multi-line declarations.
</Summary>
<Samples>
<Sample>
<Before><![CDATA[if (x &&
y &&
z)
{
}]]></Before>
<After><![CDATA[if (
x
&& y
&& z
)
{
}]]></After>
</Sample>
</Samples>
</Analyzer>
<Analyzer>
<Id>RCS9001</Id>
<Identifier>UsePatternMatching</Identifier>
Expand Down
2 changes: 1 addition & 1 deletion src/CSharp/DetermineParameterTypeHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static ImmutableArray<ITypeSymbol> DetermineParameterTypes(

if (typeSymbol?.IsErrorType() == false)
{
(typeSymbols ??= new HashSet<ITypeSymbol>()).Add(typeSymbol);
(typeSymbols ??= new HashSet<ITypeSymbol>(SymbolEqualityComparer.Default)).Add(typeSymbol);
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/Common/CSharp/CodeStyle/TargetBracesStyle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System;

namespace Roslynator.CSharp.CodeStyle;

[Flags]
public enum TargetBracesStyle
{
None,
Opening,
Closing,
Both = Opening | Closing,
}
24 changes: 24 additions & 0 deletions src/Common/CSharp/Extensions/CodeStyleExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,30 @@ public static NewLinePosition GetNullConditionalOperatorNewLinePosition(this Syn
return context.GetConfigOptions().GetNullConditionalOperatorNewLinePosition(defaultValue);
}

public static TargetBracesStyle GetTargetBracesStyle(this SyntaxNodeAnalysisContext context)
=> context.GetConfigOptions().GetTargetBracesStyle();

public static TargetBracesStyle GetTargetBracesStyle(this AnalyzerConfigOptions configOptions)
{
if (ConfigOptions.TryGetValue(configOptions, ConfigOptions.TargetBracesStyle, out string rawValue))
{
if (string.Equals(rawValue, ConfigOptionValues.TargetBracesStyle_Both, StringComparison.OrdinalIgnoreCase))
{
return TargetBracesStyle.Both;
}
else if (string.Equals(rawValue, ConfigOptionValues.TargetBracesStyle_Closing, StringComparison.OrdinalIgnoreCase))
{
return TargetBracesStyle.Closing;
}
else if (string.Equals(rawValue, ConfigOptionValues.TargetBracesStyle_Opening, StringComparison.OrdinalIgnoreCase))
{
return TargetBracesStyle.Opening;
}
}

return TargetBracesStyle.None;
}

private static bool TryGetNewLinePosition(
AnalyzerConfigOptions configOptions,
ConfigOptionDescriptor option,
Expand Down
5 changes: 4 additions & 1 deletion src/Common/CSharp/SyntaxTriviaAnalysis.cs
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ public static IndentationAnalysis AnalyzeIndentation(SyntaxNode node, AnalyzerCo
}

public static SyntaxTrivia DetermineIndentation(SyntaxNodeOrToken nodeOrToken, CancellationToken cancellationToken = default)
=> DetermineIndentation(nodeOrToken, true, cancellationToken);

public static SyntaxTrivia DetermineIndentation(SyntaxNodeOrToken nodeOrToken, bool searchInAccessors, CancellationToken cancellationToken = default)
{
SyntaxTree tree = nodeOrToken.SyntaxTree;

Expand Down Expand Up @@ -171,7 +174,7 @@ public static SyntaxTrivia DetermineIndentation(SyntaxNodeOrToken nodeOrToken, C
}
}

if (!IsMemberDeclarationOrStatementOrAccessorDeclaration(node))
if (searchInAccessors && !IsMemberDeclarationOrStatementOrAccessorDeclaration(node))
{
node = node.Parent;

Expand Down
1 change: 1 addition & 0 deletions src/Common/ConfigOptionKeys.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ internal static partial class ConfigOptionKeys
public const string PrefixFieldIdentifierWithUnderscore = "roslynator_prefix_field_identifier_with_underscore";
public const string SuppressUnityScriptMethods = "roslynator_suppress_unity_script_methods";
public const string TabLength = "roslynator_tab_length";
public const string TargetBracesStyle = "roslynator_target_braces_style";
public const string TrailingCommaStyle = "roslynator_trailing_comma_style";
public const string UnityCodeAnalysisEnabled = "roslynator_unity_code_analysis.enabled";
public const string UseAnonymousFunctionOrMethodGroup = "roslynator_use_anonymous_function_or_method_group";
Expand Down
4 changes: 4 additions & 0 deletions src/Common/ConfigOptionValues.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ internal static partial class ConfigOptionValues
public const string ObjectCreationTypeStyle_Explicit = "explicit";
public const string ObjectCreationTypeStyle_Implicit = "implicit";
public const string ObjectCreationTypeStyle_ImplicitWhenTypeIsObvious = "implicit_when_type_is_obvious";
public const string TargetBracesStyle_None = "none";
public const string TargetBracesStyle_Opening = "opening";
public const string TargetBracesStyle_Closing = "closing";
public const string TargetBracesStyle_Both = "both";
public const string TrailingCommaStyle_Include = "include";
public const string TrailingCommaStyle_Omit = "omit";
public const string TrailingCommaStyle_OmitWhenSingleLine = "omit_when_single_line";
Expand Down
6 changes: 6 additions & 0 deletions src/Common/ConfigOptions.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ public static partial class ConfigOptions
defaultValuePlaceholder: "<NUM>",
description: "A number of spaces that are equivalent to a tab character");

public static readonly ConfigOptionDescriptor TargetBracesStyle = new(
key: ConfigOptionKeys.TargetBracesStyle,
defaultValue: "none",
defaultValuePlaceholder: "both|closing|none|opening",
description: "Define which braces should be used as a target of the code fix");

public static readonly ConfigOptionDescriptor TrailingCommaStyle = new(
key: ConfigOptionKeys.TrailingCommaStyle,
defaultValue: null,
Expand Down
2 changes: 2 additions & 0 deletions src/Common/DiagnosticIdentifiers.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,5 +280,7 @@ public static partial class DiagnosticIdentifiers
public const string UseRawStringLiteral = "RCS1266";
public const string UseStringInterpolationInsteadOfStringConcat = "RCS1267";
public const string SimplifyNumericComparison = "RCS1268";
public const string FixBracketFormattingOfList = "RCS1269";
public const string FixBracketFormattingOfBinaryExpression = "RCS1270";
}
}
24 changes: 24 additions & 0 deletions src/Common/DiagnosticRules.Generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3323,5 +3323,29 @@ public static partial class DiagnosticRules
helpLinkUri: DiagnosticIdentifiers.SimplifyNumericComparison,
customTags: []);

/// <summary>RCS1269</summary>
public static readonly DiagnosticDescriptor FixBracketFormattingOfList = DiagnosticDescriptorFactory.Create(
id: DiagnosticIdentifiers.FixBracketFormattingOfList,
title: "Fix bracket formatting of a list",
messageFormat: "Fix bracket formatting of {0}",
category: DiagnosticCategories.Roslynator,
defaultSeverity: DiagnosticSeverity.Info,
isEnabledByDefault: false,
description: null,
helpLinkUri: DiagnosticIdentifiers.FixBracketFormattingOfList,
customTags: []);

/// <summary>RCS1270</summary>
public static readonly DiagnosticDescriptor FixBracketFormattingOfBinaryExpression = DiagnosticDescriptorFactory.Create(
id: DiagnosticIdentifiers.FixBracketFormattingOfBinaryExpression,
title: "Fix bracket formatting of a binary expression",
messageFormat: "Fix bracket formatting of {0}",
category: DiagnosticCategories.Roslynator,
defaultSeverity: DiagnosticSeverity.Info,
isEnabledByDefault: false,
description: null,
helpLinkUri: DiagnosticIdentifiers.FixBracketFormattingOfBinaryExpression,
customTags: []);

}
}
9 changes: 9 additions & 0 deletions src/ConfigOptions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,15 @@
<Value>when_type_is_obvious</Value>
</Values>
</Option>
<Option Id="TargetBracesStyle">
<Description>Define which braces should be used as a target of the code fix</Description>
<Values>
<Value IsDefault="true">none</Value>
<Value>opening</Value>
<Value>closing</Value>
<Value>both</Value>
</Values>
</Option>
<!--
<Option Id="">
<Key></Key>
Expand Down
22 changes: 16 additions & 6 deletions src/Documentation/DocumentationModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ internal DocumentationModel(
Assemblies = ImmutableArray.CreateRange(assemblies);
Filter = filter;

_symbolData = new Dictionary<ISymbol, SymbolDocumentationData>();
_xmlDocumentations = new Dictionary<IAssemblySymbol, XmlDocumentation>();
_symbolData = new Dictionary<ISymbol, SymbolDocumentationData>(SymbolEqualityComparer.Default);
_xmlDocumentations = new Dictionary<IAssemblySymbol, XmlDocumentation>(SymbolEqualityComparer.Default);

if (additionalXmlDocumentationPaths is not null)
_additionalXmlDocumentationPaths = additionalXmlDocumentationPaths.ToImmutableArray();
Expand All @@ -52,8 +52,8 @@ internal DocumentationModel(
Assemblies = compilations.Select(f => f.Assembly).ToImmutableArray();
Filter = filter;

_symbolData = new Dictionary<ISymbol, SymbolDocumentationData>();
_xmlDocumentations = new Dictionary<IAssemblySymbol, XmlDocumentation>();
_symbolData = new Dictionary<ISymbol, SymbolDocumentationData>(SymbolEqualityComparer.Default);
_xmlDocumentations = new Dictionary<IAssemblySymbol, XmlDocumentation>(SymbolEqualityComparer.Default);

if (additionalXmlDocumentationPaths is not null)
_additionalXmlDocumentationPaths = additionalXmlDocumentationPaths.ToImmutableArray();
Expand Down Expand Up @@ -155,7 +155,7 @@ public IEnumerable<IMethodSymbol> GetExtensionMethods(INamedTypeSymbol typeSymbo

public IEnumerable<INamedTypeSymbol> GetExtendedExternalTypes()
{
return Iterator().Distinct();
return Iterator().Distinct<INamedTypeSymbol>(SymbolEqualityComparer.Default);

IEnumerable<INamedTypeSymbol> Iterator()
{
Expand Down Expand Up @@ -433,7 +433,17 @@ private Compilation FindCompilation(IAssemblySymbol assembly)
return Compilations[0];

if (_compilationMap is null)
Interlocked.CompareExchange(ref _compilationMap, Compilations.ToImmutableDictionary(f => f.Assembly, f => f), null);
{
Interlocked.CompareExchange(
ref _compilationMap,
Compilations.ToImmutableDictionary<Compilation, IAssemblySymbol, Compilation>(
f => f.Assembly,
f => f,
SymbolEqualityComparer.Default
),
null
);
}

return _compilationMap[assembly];
}
Expand Down
Loading