diff --git a/SourceKit.sln b/SourceKit.sln
index 643eede..0b96d59 100644
--- a/SourceKit.sln
+++ b/SourceKit.sln
@@ -89,6 +89,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceKit.Analyzers.Propert
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceKit.Reflect.Samples", "samples\SourceKit.Reflect.Samples\SourceKit.Reflect.Samples.csproj", "{B3EEEF25-A90E-404F-9874-93A2E6990468}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceKit.Analyzers.MemberAccessibility.Samples", "samples\analyzers\SourceKit.Analyzers.MemberAccessibility.Samples\SourceKit.Analyzers.MemberAccessibility.Samples.csproj", "{6D49F53F-4765-4108-9AA7-1470D5FB8FD7}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceKit.Analyzers.MemberAccessibility.Tests", "tests\SourceKit.Analyzers.MemberAccessibility.Tests\SourceKit.Analyzers.MemberAccessibility.Tests.csproj", "{EACEDBCD-081E-4F95-A81E-B62CD18D3028}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -131,6 +135,8 @@ Global
{35F679FA-4F45-4870-B7C6-7B31A6CD014F} = {365210F4-5F33-49FD-9E14-552154E26285}
{4B54BDA0-D16F-428F-97D2-03654311CE22} = {CB9AFB88-6DC1-436D-8F6F-398E065A07DE}
{B3EEEF25-A90E-404F-9874-93A2E6990468} = {68973D47-37E1-492E-8F62-E94B002349BB}
+ {6D49F53F-4765-4108-9AA7-1470D5FB8FD7} = {365210F4-5F33-49FD-9E14-552154E26285}
+ {EACEDBCD-081E-4F95-A81E-B62CD18D3028} = {CB9AFB88-6DC1-436D-8F6F-398E065A07DE}
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{637C01C1-3A3C-4FC6-9874-6CFBA4319A79}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -249,5 +255,13 @@ Global
{B3EEEF25-A90E-404F-9874-93A2E6990468}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B3EEEF25-A90E-404F-9874-93A2E6990468}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B3EEEF25-A90E-404F-9874-93A2E6990468}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6D49F53F-4765-4108-9AA7-1470D5FB8FD7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {6D49F53F-4765-4108-9AA7-1470D5FB8FD7}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {6D49F53F-4765-4108-9AA7-1470D5FB8FD7}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {6D49F53F-4765-4108-9AA7-1470D5FB8FD7}.Release|Any CPU.Build.0 = Release|Any CPU
+ {EACEDBCD-081E-4F95-A81E-B62CD18D3028}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {EACEDBCD-081E-4F95-A81E-B62CD18D3028}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {EACEDBCD-081E-4F95-A81E-B62CD18D3028}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {EACEDBCD-081E-4F95-A81E-B62CD18D3028}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/.editorconfig b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/.editorconfig
new file mode 100644
index 0000000..e0f917d
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/.editorconfig
@@ -0,0 +1,5 @@
+[*.cs]
+
+dotnet_diagnostic.SK1100.severity = warning
+dotnet_diagnostic.SK1101.severity = warning
+dotnet_diagnostic.SK1102.severity = warning
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.Fixed.cs b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.Fixed.cs
new file mode 100644
index 0000000..457fc2b
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.Fixed.cs
@@ -0,0 +1,8 @@
+namespace SourceKit.Analyzers.MemberAccessibility.Samples;
+
+public class MultipleFieldsCaseFixed
+{
+ private object _first;
+ private object _second;
+ private object _third;
+}
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.cs b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.cs
new file mode 100644
index 0000000..0e47701
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.cs
@@ -0,0 +1,6 @@
+namespace SourceKit.Analyzers.MemberAccessibility.Samples;
+
+public class MultipleFieldsCase
+{
+ private object _first, _second, _third;
+}
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.Fixed.cs b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.Fixed.cs
new file mode 100644
index 0000000..43e8c56
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.Fixed.cs
@@ -0,0 +1,6 @@
+namespace SourceKit.Analyzers.MemberAccessibility.Samples;
+
+public class PrivatePropertyCaseFixed
+{
+ public object PrivateProperty { get; }
+}
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.cs b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.cs
new file mode 100644
index 0000000..1ea7a4b
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.cs
@@ -0,0 +1,6 @@
+namespace SourceKit.Analyzers.MemberAccessibility.Samples;
+
+public class PrivatePropertyCase
+{
+ private object PrivateProperty { get; }
+}
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.Fixed.cs b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.Fixed.cs
new file mode 100644
index 0000000..6c7a194
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.Fixed.cs
@@ -0,0 +1,6 @@
+namespace SourceKit.Analyzers.MemberAccessibility.Samples;
+
+public class PublicFieldTestCaseFixed
+{
+ private object _publicField;
+}
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.cs b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.cs
new file mode 100644
index 0000000..29b611d
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.cs
@@ -0,0 +1,6 @@
+namespace SourceKit.Analyzers.MemberAccessibility.Samples;
+
+public class PublicFieldTestCase
+{
+ public object _publicField;
+}
diff --git a/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/SourceKit.Analyzers.MemberAccessibility.Samples.csproj b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/SourceKit.Analyzers.MemberAccessibility.Samples.csproj
new file mode 100644
index 0000000..0fd3d83
--- /dev/null
+++ b/samples/analyzers/SourceKit.Analyzers.MemberAccessibility.Samples/SourceKit.Analyzers.MemberAccessibility.Samples.csproj
@@ -0,0 +1,23 @@
+
+
+
+ disable
+
+
+
+
+
+
+
+
+ MultipleFieldsCase.cs
+
+
+ PrivatePropertyCase.cs
+
+
+ PublicFieldTestCase.cs
+
+
+
+
diff --git a/src/analyzers/SourceKit.Analyzers.Collections/Analyzers/DictionaryKeyTypeMustImplementEquatableAnalyzer.cs b/src/analyzers/SourceKit.Analyzers.Collections/Analyzers/DictionaryKeyTypeMustImplementEquatableAnalyzer.cs
index a283d09..45b35ac 100644
--- a/src/analyzers/SourceKit.Analyzers.Collections/Analyzers/DictionaryKeyTypeMustImplementEquatableAnalyzer.cs
+++ b/src/analyzers/SourceKit.Analyzers.Collections/Analyzers/DictionaryKeyTypeMustImplementEquatableAnalyzer.cs
@@ -36,7 +36,7 @@ private void AnalyzeGeneric(SyntaxNodeAnalysisContext context)
{
var node = (GenericNameSyntax)context.Node;
- if (context.SemanticModel.GetDeclaredSymbol(node) is not INamedTypeSymbol symbol)
+ if (context.SemanticModel.GetSymbolInfo(node).Symbol is not INamedTypeSymbol symbol)
return;
if (TryGetDictionaryKeySymbol(symbol, typeof(Dictionary<,>), context, out INamedTypeSymbol? keySymbol) is false
@@ -54,17 +54,14 @@ private void AnalyzeGeneric(SyntaxNodeAnalysisContext context)
INamedTypeSymbol equatableSymbol = context.Compilation.GetTypeSymbol(typeof(IEquatable<>));
- INamedTypeSymbol madeEquatableSymbol = equatableSymbol
- .Construct(keySymbol.WithNullableAnnotation(NullableAnnotation.None));
-
IEnumerable foundEquatableSymbols = keySymbol
.FindAssignableTypesConstructedFrom(equatableSymbol);
bool hasCorrectEquatableImplementation = foundEquatableSymbols
.Select(x => x.TypeArguments.First())
- .Any(x => madeEquatableSymbol.Equals(x, SymbolEqualityComparer.Default));
+ .Any(x => keySymbol.Equals(x, SymbolEqualityComparer.Default) || keySymbol.IsAssignableTo(x));
- if (hasCorrectEquatableImplementation is false)
+ if (hasCorrectEquatableImplementation)
return;
var diag = Diagnostic.Create(Descriptor, node.GetLocation());
diff --git a/src/analyzers/SourceKit.Analyzers.Collections/CodeFixes/ConvertListForEachIntoForEachLoopCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.Collections/CodeFixes/ConvertListForEachIntoForEachLoopCodeFixProvider.cs
index 03981bb..b31acd8 100644
--- a/src/analyzers/SourceKit.Analyzers.Collections/CodeFixes/ConvertListForEachIntoForEachLoopCodeFixProvider.cs
+++ b/src/analyzers/SourceKit.Analyzers.Collections/CodeFixes/ConvertListForEachIntoForEachLoopCodeFixProvider.cs
@@ -42,8 +42,9 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
context.RegisterCodeFix(
CodeAction.Create(
- equivalenceKey: ListForEachNotAllowedAnalyzer.DiagnosticId,
title: Title,
+ priority: CodeActionPriority.High,
+ equivalenceKey: ListForEachNotAllowedAnalyzer.DiagnosticId,
createChangedDocument: cancellationToken =>
ConvertListForEachIntoLoop(context.Document, invocationExpression, cancellationToken)),
diagnostic);
diff --git a/src/analyzers/SourceKit.Analyzers.Enumerable/CodeFixes/RemoveTerminalOperationCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.Enumerable/CodeFixes/RemoveTerminalOperationCodeFixProvider.cs
index 29489b5..afbffa3 100644
--- a/src/analyzers/SourceKit.Analyzers.Enumerable/CodeFixes/RemoveTerminalOperationCodeFixProvider.cs
+++ b/src/analyzers/SourceKit.Analyzers.Enumerable/CodeFixes/RemoveTerminalOperationCodeFixProvider.cs
@@ -34,6 +34,7 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
var codeFixAction = CodeAction.Create(
title: title,
+ priority: CodeActionPriority.High,
createChangedSolution: c => RemoveToList(context.Document, node, c),
equivalenceKey: title);
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/AnalyzerReleases.Unshipped.md b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/AnalyzerReleases.Unshipped.md
index be321c3..c00b7bb 100644
--- a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/AnalyzerReleases.Unshipped.md
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/AnalyzerReleases.Unshipped.md
@@ -3,4 +3,5 @@
Rule ID | Category | Severity | Notes
--------|----------|----------|--------------------
SK1100 | Design | Error | Do not use private properties
-SK1101 | Design | Error | Do not use public fields
\ No newline at end of file
+SK1101 | Design | Error | Do not use public fields
+SK1102 | Design | Error | Do not use multiple fields
\ No newline at end of file
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/FieldCannotBePublicAnalyzer.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/FieldCannotBePublicAnalyzer.cs
index a30fe73..fd35376 100644
--- a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/FieldCannotBePublicAnalyzer.cs
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/FieldCannotBePublicAnalyzer.cs
@@ -1,5 +1,7 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace SourceKit.Analyzers.MemberAccessibility.Analyzers;
@@ -8,9 +10,9 @@ namespace SourceKit.Analyzers.MemberAccessibility.Analyzers;
public class FieldCannotBePublicAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "SK1101";
- public const string Title = nameof(PropertyCannotBePrivateAnalyzer);
+ public const string Title = nameof(FieldCannotBePublicAnalyzer);
- public const string Format = """Field {0} {1} cannot be public""";
+ public const string Format = """Field '{0} {1}' cannot be public""";
public static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(
DiagnosticId,
@@ -27,5 +29,24 @@ public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+ context.RegisterSyntaxNodeAction(AnalyzeField, SyntaxKind.FieldDeclaration);
}
-}
\ No newline at end of file
+
+ private void AnalyzeField(SyntaxNodeAnalysisContext context)
+ {
+ var fieldSyntax = (FieldDeclarationSyntax)context.Node;
+
+ if (fieldSyntax.Modifiers.All(x => x.IsKind(SyntaxKind.PublicKeyword) is false))
+ {
+ return;
+ }
+
+ foreach (VariableDeclaratorSyntax variable in fieldSyntax.Declaration.Variables)
+ {
+ Location location = variable.GetLocation();
+ var diagnostic = Diagnostic.Create(Descriptor, location, fieldSyntax.Declaration.Type, variable.Identifier.Text);
+
+ context.ReportDiagnostic(diagnostic);
+ }
+ }
+}
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/FieldCannotHaveMultipleVariablesAnalyzer.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/FieldCannotHaveMultipleVariablesAnalyzer.cs
new file mode 100644
index 0000000..50247dd
--- /dev/null
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/FieldCannotHaveMultipleVariablesAnalyzer.cs
@@ -0,0 +1,48 @@
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Diagnostics;
+
+namespace SourceKit.Analyzers.MemberAccessibility.Analyzers;
+
+[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
+public class FieldCannotHaveMultipleVariablesAnalyzer : DiagnosticAnalyzer
+{
+ public const string DiagnosticId = "SK1102";
+ public const string Title = nameof(FieldCannotHaveMultipleVariablesAnalyzer);
+
+ public const string Format = """Each field must have separate declaration""";
+
+ public static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(DiagnosticId,
+ Title,
+ Format,
+ "Design",
+ DiagnosticSeverity.Error,
+ true);
+
+ public override ImmutableArray SupportedDiagnostics { get; } =
+ ImmutableArray.Create(Descriptor);
+
+ public override void Initialize(AnalysisContext context)
+ {
+ context.EnableConcurrentExecution();
+ context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+ context.RegisterSyntaxNodeAction(AnalyzeField, SyntaxKind.FieldDeclaration);
+ }
+
+ private void AnalyzeField(SyntaxNodeAnalysisContext context)
+ {
+ var fieldSyntax = (FieldDeclarationSyntax)context.Node;
+
+ if (fieldSyntax.Declaration.Variables.Count <= 1)
+ {
+ return;
+ }
+
+ Location location = fieldSyntax.GetLocation();
+ var diagnostic = Diagnostic.Create(Descriptor, location);
+
+ context.ReportDiagnostic(diagnostic);
+ }
+}
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/PropertyCannotBePrivateAnalyzer.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/PropertyCannotBePrivateAnalyzer.cs
index 6351a60..f64bf33 100644
--- a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/PropertyCannotBePrivateAnalyzer.cs
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/Analyzers/PropertyCannotBePrivateAnalyzer.cs
@@ -1,5 +1,7 @@
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Diagnostics;
namespace SourceKit.Analyzers.MemberAccessibility.Analyzers;
@@ -10,10 +12,9 @@ public class PropertyCannotBePrivateAnalyzer : DiagnosticAnalyzer
public const string DiagnosticId = "SK1100";
public const string Title = nameof(PropertyCannotBePrivateAnalyzer);
- public const string Format = """Property {0} {1} cannot be private""";
+ public const string Format = """Property '{0} {1}' cannot be private""";
- public static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(
- DiagnosticId,
+ public static readonly DiagnosticDescriptor Descriptor = new DiagnosticDescriptor(DiagnosticId,
Title,
Format,
"Design",
@@ -27,5 +28,21 @@ public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
+ context.RegisterSyntaxNodeAction(AnalyzeProperty, SyntaxKind.PropertyDeclaration);
}
-}
\ No newline at end of file
+
+ private void AnalyzeProperty(SyntaxNodeAnalysisContext context)
+ {
+ var propertySyntax = (PropertyDeclarationSyntax)context.Node;
+
+ if (propertySyntax.Modifiers.All(x => x.IsKind(SyntaxKind.PrivateKeyword) is false))
+ {
+ return;
+ }
+
+ Location location = propertySyntax.GetLocation();
+ var diagnostic = Diagnostic.Create(Descriptor, location, propertySyntax.Type, propertySyntax.Identifier.Text);
+
+ context.ReportDiagnostic(diagnostic);
+ }
+}
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldAccessibilityCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldAccessibilityCodeFixProvider.cs
deleted file mode 100644
index 698e242..0000000
--- a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldAccessibilityCodeFixProvider.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CodeFixes;
-using SourceKit.Analyzers.MemberAccessibility.Analyzers;
-
-namespace SourceKit.Analyzers.MemberAccessibility.CodeFixes;
-
-[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(FieldAccessibilityCodeFixProvider))]
-public class FieldAccessibilityCodeFixProvider : CodeFixProvider
-{
- public const string Title = "Make field private";
-
- public override ImmutableArray FixableDiagnosticIds { get; } =
- ImmutableArray.Create(FieldCannotBePublicAnalyzer.DiagnosticId);
-
- public override FixAllProvider GetFixAllProvider()
- => WellKnownFixAllProviders.BatchFixer;
-
- public override Task RegisterCodeFixesAsync(CodeFixContext context)
- {
- return Task.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldCannotBePublicCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldCannotBePublicCodeFixProvider.cs
new file mode 100644
index 0000000..e612cb2
--- /dev/null
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldCannotBePublicCodeFixProvider.cs
@@ -0,0 +1,62 @@
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace SourceKit.Analyzers.MemberAccessibility.CodeFixes;
+
+[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(FieldCannotBePublicCodeFixProvider))]
+public class FieldCannotBePublicCodeFixProvider : CodeFixProvider
+{
+ public const string Title = "Make field private";
+
+ public override ImmutableArray FixableDiagnosticIds { get; } =
+ ImmutableArray.Create(FieldCannotBePublicAnalyzer.DiagnosticId);
+
+ public override FixAllProvider GetFixAllProvider()
+ => WellKnownFixAllProviders.BatchFixer;
+
+ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ context.CancellationToken.ThrowIfCancellationRequested();
+
+ IEnumerable derivativesMustBePartialDiagnostics = context.Diagnostics
+ .Select(x => ProvideDerivativesMustBePartial(context, x));
+
+ await Task.WhenAll(derivativesMustBePartialDiagnostics);
+ }
+
+ private static async Task ProvideDerivativesMustBePartial(CodeFixContext context, Diagnostic diagnostic)
+ {
+ var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
+
+ if (root?.FindNode(diagnostic.Location.SourceSpan) is not { Parent.Parent: FieldDeclarationSyntax fieldSyntax })
+ return;
+
+ var action = CodeAction.Create(
+ title: Title,
+ priority: CodeActionPriority.High,
+ equivalenceKey: nameof(FieldCannotBePublicCodeFixProvider),
+ createChangedDocument: _ =>
+ {
+ SyntaxToken privateModifier = fieldSyntax.Modifiers.First(x => x.IsKind(SyntaxKind.PublicKeyword));
+
+ SyntaxTokenList fixedModifiers = fieldSyntax.Modifiers
+ .Replace(privateModifier, Token(SyntaxKind.PrivateKeyword));
+
+ FieldDeclarationSyntax fixedSyntax = fieldSyntax.WithModifiers(fixedModifiers);
+
+ SyntaxNode newRoot = root.ReplaceNode(fieldSyntax, fixedSyntax);
+
+ Document document = context.Document.WithSyntaxRoot(newRoot);
+
+ return Task.FromResult(document);
+ });
+
+ context.RegisterCodeFix(action, diagnostic);
+ }
+}
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldCannotHaveMultipleVariablesCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldCannotHaveMultipleVariablesCodeFixProvider.cs
new file mode 100644
index 0000000..9180303
--- /dev/null
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/FieldCannotHaveMultipleVariablesCodeFixProvider.cs
@@ -0,0 +1,62 @@
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace SourceKit.Analyzers.MemberAccessibility.CodeFixes;
+
+[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(PropertyCannotBePrivateCodeFixProvider))]
+public class FieldCannotHaveMultipleVariablesCodeFixProvider : CodeFixProvider
+{
+ public const string Title = "Separate field declarations";
+
+ public override ImmutableArray FixableDiagnosticIds { get; } =
+ ImmutableArray.Create(FieldCannotHaveMultipleVariablesAnalyzer.DiagnosticId);
+
+ public override FixAllProvider GetFixAllProvider()
+ => WellKnownFixAllProviders.BatchFixer;
+
+ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ context.CancellationToken.ThrowIfCancellationRequested();
+
+ IEnumerable derivativesMustBePartialDiagnostics = context.Diagnostics
+ .Select(x => ProvideDerivativesMustBePartial(context, x));
+
+ await Task.WhenAll(derivativesMustBePartialDiagnostics);
+ }
+
+ private static async Task ProvideDerivativesMustBePartial(CodeFixContext context, Diagnostic diagnostic)
+ {
+ var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
+
+ if (root?.FindNode(diagnostic.Location.SourceSpan) is not FieldDeclarationSyntax fieldSyntax)
+ return;
+
+ var action = CodeAction.Create(
+ title: Title,
+ priority: CodeActionPriority.High,
+ equivalenceKey: nameof(FieldCannotHaveMultipleVariablesCodeFixProvider),
+ createChangedDocument: _ =>
+ {
+ IEnumerable fixedFields = fieldSyntax.Declaration.Variables.Select(x =>
+ {
+ VariableDeclarationSyntax declaration = fieldSyntax.Declaration
+ .WithVariables(SingletonSeparatedList(x));
+
+ return fieldSyntax.WithDeclaration(declaration);
+ });
+
+ SyntaxNode newRoot = root.ReplaceNode(fieldSyntax, fixedFields);
+
+ Document document = context.Document.WithSyntaxRoot(newRoot);
+
+ return Task.FromResult(document);
+ });
+
+ context.RegisterCodeFix(action, diagnostic);
+ }
+}
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/PropertyAccessibilityCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/PropertyAccessibilityCodeFixProvider.cs
deleted file mode 100644
index bb6bfe9..0000000
--- a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/PropertyAccessibilityCodeFixProvider.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System.Collections.Immutable;
-using Microsoft.CodeAnalysis;
-using Microsoft.CodeAnalysis.CodeFixes;
-using SourceKit.Analyzers.MemberAccessibility.Analyzers;
-
-namespace SourceKit.Analyzers.MemberAccessibility.CodeFixes;
-
-[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(PropertyAccessibilityCodeFixProvider))]
-public class PropertyAccessibilityCodeFixProvider : CodeFixProvider
-{
- public const string PublicTitle = "Make property public";
- public const string ProtectedTitle = "Make property protected";
-
- public override ImmutableArray FixableDiagnosticIds { get; } =
- ImmutableArray.Create(PropertyCannotBePrivateAnalyzer.DiagnosticId);
-
- public override FixAllProvider GetFixAllProvider()
- => WellKnownFixAllProviders.BatchFixer;
-
- public override Task RegisterCodeFixesAsync(CodeFixContext context)
- {
- return Task.CompletedTask;
- }
-}
\ No newline at end of file
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/PropertyCannotBePrivateCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/PropertyCannotBePrivateCodeFixProvider.cs
new file mode 100644
index 0000000..4872508
--- /dev/null
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/CodeFixes/PropertyCannotBePrivateCodeFixProvider.cs
@@ -0,0 +1,62 @@
+using System.Collections.Immutable;
+using Microsoft.CodeAnalysis;
+using Microsoft.CodeAnalysis.CodeActions;
+using Microsoft.CodeAnalysis.CodeFixes;
+using Microsoft.CodeAnalysis.CSharp;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory;
+
+namespace SourceKit.Analyzers.MemberAccessibility.CodeFixes;
+
+[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(PropertyCannotBePrivateCodeFixProvider))]
+public class PropertyCannotBePrivateCodeFixProvider : CodeFixProvider
+{
+ public const string Title = "Make property public";
+
+ public override ImmutableArray FixableDiagnosticIds { get; } =
+ ImmutableArray.Create(PropertyCannotBePrivateAnalyzer.DiagnosticId);
+
+ public override FixAllProvider GetFixAllProvider()
+ => WellKnownFixAllProviders.BatchFixer;
+
+ public override async Task RegisterCodeFixesAsync(CodeFixContext context)
+ {
+ context.CancellationToken.ThrowIfCancellationRequested();
+
+ IEnumerable derivativesMustBePartialDiagnostics = context.Diagnostics
+ .Select(x => ProvideDerivativesMustBePartial(context, x));
+
+ await Task.WhenAll(derivativesMustBePartialDiagnostics);
+ }
+
+ private static async Task ProvideDerivativesMustBePartial(CodeFixContext context, Diagnostic diagnostic)
+ {
+ var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
+
+ if (root?.FindNode(diagnostic.Location.SourceSpan) is not PropertyDeclarationSyntax propertySyntax)
+ return;
+
+ var action = CodeAction.Create(
+ title: Title,
+ priority: CodeActionPriority.High,
+ equivalenceKey: nameof(PropertyCannotBePrivateCodeFixProvider),
+ createChangedDocument: _ =>
+ {
+ SyntaxToken privateModifier = propertySyntax.Modifiers.First(x => x.IsKind(SyntaxKind.PrivateKeyword));
+
+ SyntaxTokenList fixedModifiers = propertySyntax.Modifiers
+ .Replace(privateModifier, Token(SyntaxKind.PublicKeyword));
+
+ PropertyDeclarationSyntax fixedSyntax = propertySyntax.WithModifiers(fixedModifiers);
+
+ SyntaxNode newRoot = root.ReplaceNode(propertySyntax, fixedSyntax);
+
+ Document document = context.Document.WithSyntaxRoot(newRoot);
+
+ return Task.FromResult(document);
+ });
+
+ context.RegisterCodeFix(action, diagnostic);
+ }
+}
diff --git a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/SourceKit.Analyzers.MemberAccessibility.csproj b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/SourceKit.Analyzers.MemberAccessibility.csproj
index 33c1cf8..010d4bc 100644
--- a/src/analyzers/SourceKit.Analyzers.MemberAccessibility/SourceKit.Analyzers.MemberAccessibility.csproj
+++ b/src/analyzers/SourceKit.Analyzers.MemberAccessibility/SourceKit.Analyzers.MemberAccessibility.csproj
@@ -8,7 +8,7 @@
true
false
- false
+ true
diff --git a/src/analyzers/SourceKit.Analyzers.MustBePartial/CodeFixes/MakeTypePartialCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.MustBePartial/CodeFixes/MakeTypePartialCodeFixProvider.cs
index fba458c..0349941 100644
--- a/src/analyzers/SourceKit.Analyzers.MustBePartial/CodeFixes/MakeTypePartialCodeFixProvider.cs
+++ b/src/analyzers/SourceKit.Analyzers.MustBePartial/CodeFixes/MakeTypePartialCodeFixProvider.cs
@@ -35,11 +35,12 @@ private static async Task ProvideDerivativesMustBePartial(CodeFixContext context
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);
- if (root?.FindNode(context.Span) is not TypeDeclarationSyntax syntax)
+ if (root?.FindNode(diagnostic.Location.SourceSpan) is not TypeDeclarationSyntax syntax)
return;
var action = CodeAction.Create(
- Title,
+ title: Title,
+ priority: CodeActionPriority.High,
equivalenceKey: nameof(Title),
createChangedDocument: _ =>
{
diff --git a/src/analyzers/SourceKit.Analyzers.Nullable/CodeFixes/PropagateNullableCorrectlyCodeFixProvider.cs b/src/analyzers/SourceKit.Analyzers.Nullable/CodeFixes/PropagateNullableCorrectlyCodeFixProvider.cs
index 5927c8b..8b99c12 100644
--- a/src/analyzers/SourceKit.Analyzers.Nullable/CodeFixes/PropagateNullableCorrectlyCodeFixProvider.cs
+++ b/src/analyzers/SourceKit.Analyzers.Nullable/CodeFixes/PropagateNullableCorrectlyCodeFixProvider.cs
@@ -66,6 +66,7 @@ private async Task FixDiagnostic(CodeFixContext context, DocumentEditor editor,
context.RegisterCodeFix(
CodeAction.Create(
title: Title,
+ priority: CodeActionPriority.High,
createChangedDocument: c =>
{
var changedDocument = editor.GetChangedDocument();
diff --git a/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/FieldCannotBePublicAnalyzerTests.cs b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/FieldCannotBePublicAnalyzerTests.cs
new file mode 100644
index 0000000..ab1710d
--- /dev/null
+++ b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/FieldCannotBePublicAnalyzerTests.cs
@@ -0,0 +1,28 @@
+using Microsoft.CodeAnalysis.Testing;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using SourceKit.Tests.Common;
+using SourceKit.Tests.Common.TestBases;
+using Xunit;
+
+namespace SourceKit.Analyzers.MemberAccessibility.Tests.Analyzers;
+
+public class FieldCannotBePublicAnalyzerTests : AnalyzerTestBase
+{
+ [Fact]
+ public async Task ShouldReportDiagnostic_WhenFieldIsPublic()
+ {
+ SourceFile sourceFile = await SourceFile
+ .LoadAsync("SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.cs");
+
+ DiagnosticResult diagnostic = AnalyzerVerifier
+ .Diagnostic(FieldCannotBePublicAnalyzer.Descriptor)
+ .WithLocation(sourceFile.Name, 5, 19)
+ .WithArguments("object", "_publicField");
+
+ await AnalyzerTest
+ .WithSource(sourceFile)
+ .WithExpectedDiagnostic(diagnostic)
+ .Build()
+ .RunAsync();
+ }
+}
diff --git a/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/FieldCannotHaveMultipleVariablesAnalyzerTests.cs b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/FieldCannotHaveMultipleVariablesAnalyzerTests.cs
new file mode 100644
index 0000000..cbe517d
--- /dev/null
+++ b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/FieldCannotHaveMultipleVariablesAnalyzerTests.cs
@@ -0,0 +1,27 @@
+using Microsoft.CodeAnalysis.Testing;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using SourceKit.Tests.Common;
+using SourceKit.Tests.Common.TestBases;
+using Xunit;
+
+namespace SourceKit.Analyzers.MemberAccessibility.Tests.Analyzers;
+
+public class FieldCannotHaveMultipleVariablesAnalyzerTests : AnalyzerTestBase
+{
+ [Fact]
+ public async Task ShouldReportDiagnostic_WhenMultipleFields()
+ {
+ SourceFile sourceFile = await SourceFile
+ .LoadAsync("SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.cs");
+
+ DiagnosticResult diagnostic = AnalyzerVerifier
+ .Diagnostic(FieldCannotHaveMultipleVariablesAnalyzer.Descriptor)
+ .WithLocation(sourceFile.Name, 5, 5);
+
+ await AnalyzerTest
+ .WithSource(sourceFile)
+ .WithExpectedDiagnostic(diagnostic)
+ .Build()
+ .RunAsync();
+ }
+}
diff --git a/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/PropertyCannotBePrivateAnalyzerTests.cs b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/PropertyCannotBePrivateAnalyzerTests.cs
new file mode 100644
index 0000000..5d05353
--- /dev/null
+++ b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/Analyzers/PropertyCannotBePrivateAnalyzerTests.cs
@@ -0,0 +1,28 @@
+using Microsoft.CodeAnalysis.Testing;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using SourceKit.Tests.Common;
+using SourceKit.Tests.Common.TestBases;
+using Xunit;
+
+namespace SourceKit.Analyzers.MemberAccessibility.Tests.Analyzers;
+
+public class PropertyCannotBePrivateAnalyzerTests : AnalyzerTestBase
+{
+ [Fact]
+ public async Task ShouldReportDiagnostic_WhenPropertyIsPrivate()
+ {
+ SourceFile sourceFile = await SourceFile.LoadAsync(
+ "SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.cs");
+
+ DiagnosticResult diagnostic = AnalyzerVerifier
+ .Diagnostic(PropertyCannotBePrivateAnalyzer.Descriptor)
+ .WithLocation(sourceFile.Name, 5, 5)
+ .WithArguments("object", "PrivateProperty");
+
+ await AnalyzerTest
+ .WithSource(sourceFile)
+ .WithExpectedDiagnostic(diagnostic)
+ .Build()
+ .RunAsync();
+ }
+}
diff --git a/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/FieldCannotBePublicCodeFixTests.cs b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/FieldCannotBePublicCodeFixTests.cs
new file mode 100644
index 0000000..78a89ca
--- /dev/null
+++ b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/FieldCannotBePublicCodeFixTests.cs
@@ -0,0 +1,37 @@
+using Microsoft.CodeAnalysis.Testing;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using SourceKit.Analyzers.MemberAccessibility.CodeFixes;
+using SourceKit.Tests.Common;
+using SourceKit.Tests.Common.TestBases;
+using Xunit;
+
+namespace SourceKit.Analyzers.MemberAccessibility.Tests.CodeFixes;
+
+public class FieldCannotBePublicCodeFixTests : CodeFixTestBase
+{
+ [Fact]
+ public async Task ShouldMakePropertyPublic_WhenDiagnosticReported()
+ {
+ SourceFile sourceFile = await SourceFile.LoadAsync(
+ "SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.cs");
+
+ SourceFile fixedSourceFile = await SourceFile.LoadAsync(
+ "SourceKit.Analyzers.MemberAccessibility.Samples/PublicFieldTestCase.Fixed.cs");
+
+ string fixedContent = fixedSourceFile.Content.Replace("PublicFieldTestCaseFixed", "PublicFieldTestCase");
+
+ fixedSourceFile = sourceFile with { Content = fixedContent };
+
+ DiagnosticResult diagnostic = AnalyzerVerifier
+ .Diagnostic(FieldCannotBePublicAnalyzer.Descriptor)
+ .WithLocation(sourceFile.Name, 5, 19)
+ .WithArguments("object", "_publicField");
+
+ await CodeFixTest
+ .WithSource(sourceFile)
+ .WithFixedSource(fixedSourceFile)
+ .WithExpectedDiagnostic(diagnostic)
+ .Build()
+ .RunAsync();
+ }
+}
diff --git a/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/FieldCannotHaveMultipleVariablesCodeFixTests.cs b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/FieldCannotHaveMultipleVariablesCodeFixTests.cs
new file mode 100644
index 0000000..0d427c5
--- /dev/null
+++ b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/FieldCannotHaveMultipleVariablesCodeFixTests.cs
@@ -0,0 +1,36 @@
+using Microsoft.CodeAnalysis.Testing;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using SourceKit.Analyzers.MemberAccessibility.CodeFixes;
+using SourceKit.Tests.Common;
+using SourceKit.Tests.Common.TestBases;
+using Xunit;
+
+namespace SourceKit.Analyzers.MemberAccessibility.Tests.CodeFixes;
+
+public class FieldCannotHaveMultipleVariablesCodeFixTests : CodeFixTestBase
+{
+ [Fact]
+ public async Task ShouldMakePropertyPublic_WhenDiagnosticReported()
+ {
+ SourceFile sourceFile = await SourceFile.LoadAsync(
+ "SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.cs");
+
+ SourceFile fixedSourceFile = await SourceFile.LoadAsync(
+ "SourceKit.Analyzers.MemberAccessibility.Samples/MultipleFieldsCase.Fixed.cs");
+
+ string fixedContent = fixedSourceFile.Content.Replace("MultipleFieldsCaseFixed", "MultipleFieldsCase");
+
+ fixedSourceFile = sourceFile with { Content = fixedContent };
+
+ DiagnosticResult diagnostic = AnalyzerVerifier
+ .Diagnostic(FieldCannotHaveMultipleVariablesAnalyzer.Descriptor)
+ .WithLocation(sourceFile.Name, 5, 5);
+
+ await CodeFixTest
+ .WithSource(sourceFile)
+ .WithFixedSource(fixedSourceFile)
+ .WithExpectedDiagnostic(diagnostic)
+ .Build()
+ .RunAsync();
+ }
+}
diff --git a/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/PropertyCannotBePrivateCodeFixTests.cs b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/PropertyCannotBePrivateCodeFixTests.cs
new file mode 100644
index 0000000..4bfc862
--- /dev/null
+++ b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/CodeFixes/PropertyCannotBePrivateCodeFixTests.cs
@@ -0,0 +1,37 @@
+using Microsoft.CodeAnalysis.Testing;
+using SourceKit.Analyzers.MemberAccessibility.Analyzers;
+using SourceKit.Analyzers.MemberAccessibility.CodeFixes;
+using SourceKit.Tests.Common;
+using SourceKit.Tests.Common.TestBases;
+using Xunit;
+
+namespace SourceKit.Analyzers.MemberAccessibility.Tests.CodeFixes;
+
+public class PropertyCannotBePrivateCodeFixTests : CodeFixTestBase
+{
+ [Fact]
+ public async Task ShouldMakePropertyPublic_WhenDiagnosticReported()
+ {
+ SourceFile sourceFile = await SourceFile.LoadAsync(
+ "SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.cs");
+
+ SourceFile fixedSourceFile = await SourceFile.LoadAsync(
+ "SourceKit.Analyzers.MemberAccessibility.Samples/PrivatePropertyCase.Fixed.cs");
+
+ string fixedContent = fixedSourceFile.Content.Replace("PrivatePropertyCaseFixed", "PrivatePropertyCase");
+
+ fixedSourceFile = sourceFile with { Content = fixedContent };
+
+ DiagnosticResult diagnostic = AnalyzerVerifier
+ .Diagnostic(PropertyCannotBePrivateAnalyzer.Descriptor)
+ .WithLocation(sourceFile.Name, 5, 5)
+ .WithArguments("object", "PrivateProperty");
+
+ await CodeFixTest
+ .WithSource(sourceFile)
+ .WithFixedSource(fixedSourceFile)
+ .WithExpectedDiagnostic(diagnostic)
+ .Build()
+ .RunAsync();
+ }
+}
diff --git a/tests/SourceKit.Analyzers.MemberAccessibility.Tests/SourceKit.Analyzers.MemberAccessibility.Tests.csproj b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/SourceKit.Analyzers.MemberAccessibility.Tests.csproj
new file mode 100644
index 0000000..4ae33fe
--- /dev/null
+++ b/tests/SourceKit.Analyzers.MemberAccessibility.Tests/SourceKit.Analyzers.MemberAccessibility.Tests.csproj
@@ -0,0 +1,30 @@
+
+
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/SourceKit.Generators.Builder.Tests/BuilderSourceGeneratorTests.cs b/tests/SourceKit.Generators.Builder.Tests/BuilderSourceGeneratorTests.cs
index 6b71bc5..ed95d2a 100644
--- a/tests/SourceKit.Generators.Builder.Tests/BuilderSourceGeneratorTests.cs
+++ b/tests/SourceKit.Generators.Builder.Tests/BuilderSourceGeneratorTests.cs
@@ -28,6 +28,7 @@ public async Task ShouldGenerateCorrectBuilderType()
using System.Collections.Generic;
using System.Linq;
+ #nullable enable
namespace SourceKit.Generators.Builder.Samples
{
public partial record SomeQuery
@@ -39,39 +40,39 @@ public static SomeQuery Build(Func action)
public sealed partial class Builder
{
- private readonly List _ids;
- private Int32 _count;
- private Nullable _orderById;
+ private readonly global::System.Collections.Generic.List _ids;
+ private int _count;
+ private int? _orderById;
public Builder()
{
- _ids = new List();
+ _ids = new global::System.Collections.Generic.List();
_count = default;
_orderById = default;
}
[InitializesPropertyAttribute(nameof(Ids))]
- public Builder WithId(Guid element)
+ public Builder WithId(global::System.Guid element)
{
_ids.Add(element);
return this;
}
[InitializesPropertyAttribute(nameof(Ids))]
- public Builder WithIds(IEnumerable elements)
+ public Builder WithIds(global::System.Collections.Generic.IEnumerable elements)
{
_ids.AddRange(elements);
return this;
}
[InitializesPropertyAttribute(nameof(Count))]
- public Builder WithCount(Int32 value)
+ public Builder WithCount(int value)
{
_count = value;
return this;
}
[InitializesPropertyAttribute(nameof(OrderById))]
- public Builder WithOrderById(Nullable value)
+ public Builder WithOrderById(int? value)
{
_orderById = value;
return this;
@@ -114,6 +115,7 @@ public async Task ShouldGenerateCorrectBuilderType_WhenPropertyIsArray()
using System.Collections.Generic;
using System.Linq;
+ #nullable enable
namespace SourceKit.Generators.Builder.Samples
{
public partial record ArrayQuery
@@ -125,21 +127,21 @@ public static ArrayQuery Build(Func action)
public sealed partial class Builder
{
- private readonly List _ids;
+ private readonly global::System.Collections.Generic.List _ids;
public Builder()
{
- _ids = new List();
+ _ids = new global::System.Collections.Generic.List();
}
[InitializesPropertyAttribute(nameof(Ids))]
- public Builder WithId(Guid element)
+ public Builder WithId(global::System.Guid element)
{
_ids.Add(element);
return this;
}
[InitializesPropertyAttribute(nameof(Ids))]
- public Builder WithIds(IEnumerable elements)
+ public Builder WithIds(global::System.Collections.Generic.IEnumerable elements)
{
_ids.AddRange(elements);
return this;
@@ -182,6 +184,7 @@ public async Task ShouldGenerateCorrectBuilderType_WhenPropertyHasCustomType()
using System.Collections.Generic;
using System.Linq;
+ #nullable enable
namespace SourceKit.Generators.Builder.Samples
{
public partial record ArrayQuery
@@ -193,21 +196,21 @@ public static ArrayQuery Build(Func action)
public sealed partial class Builder
{
- private readonly List _ids;
+ private readonly global::System.Collections.Generic.List _ids;
public Builder()
{
- _ids = new List();
+ _ids = new global::System.Collections.Generic.List();
}
[InitializesPropertyAttribute(nameof(Ids))]
- public Builder WithId(Guid element)
+ public Builder WithId(global::System.Guid element)
{
_ids.Add(element);
return this;
}
[InitializesPropertyAttribute(nameof(Ids))]
- public Builder WithIds(IEnumerable elements)
+ public Builder WithIds(global::System.Collections.Generic.IEnumerable elements)
{
_ids.AddRange(elements);
return this;
@@ -251,34 +254,35 @@ public async Task ShouldGenerateCorrectBuilderType_WhenPropertyHasBuilderConstru
using System.Collections.Generic;
using System.Linq;
+ #nullable enable
namespace SourceKit.Generators.Builder.Samples.BuilderConstructorParameter
{
public partial record IntegerConstructorParameterQuery
{
- public static IntegerConstructorParameterQuery Build(Nullable Id, Func action)
+ public static IntegerConstructorParameterQuery Build(int? Id, Func action)
{
return action(new Builder(Id)).Build();
}
public sealed partial class Builder
{
- private Nullable _id;
- private String _value;
- public Builder(Nullable Id)
+ private int? _id;
+ private string? _value;
+ public Builder(int? Id)
{
_id = Id;
_value = string.Empty;
}
[InitializesPropertyAttribute(nameof(Id))]
- public Builder WithId(Nullable value)
+ public Builder WithId(int? value)
{
_id = value;
return this;
}
[InitializesPropertyAttribute(nameof(Value))]
- public Builder WithValue(String value)
+ public Builder WithValue(string value)
{
_value = value;
return this;
@@ -286,7 +290,7 @@ public Builder WithValue(String value)
public IntegerConstructorParameterQuery Build()
{
- return new IntegerConstructorParameterQuery(_id, _value);
+ return new IntegerConstructorParameterQuery(_id, _value ?? throw new System.ArgumentNullException(nameof(_value)));
}
}
}
diff --git a/tests/SourceKit.Generators.Grpc.Tests/ProtoMessageConstructorGeneratorTests.cs b/tests/SourceKit.Generators.Grpc.Tests/ProtoMessageConstructorGeneratorTests.cs
index 46fd128..de39567 100644
--- a/tests/SourceKit.Generators.Grpc.Tests/ProtoMessageConstructorGeneratorTests.cs
+++ b/tests/SourceKit.Generators.Grpc.Tests/ProtoMessageConstructorGeneratorTests.cs
@@ -648,12 +648,12 @@ public void MergeFrom(pb::CodedInputStream input) {
var generatedSource = new SourceFile(
Name: """
- SourceKit.Generators.Grpc/SourceKit.Generators.Grpc.Generators.ProtoMessageConstructorGenerator/ProtoModel.SourceKit.Generators.Grpc.g.cs
+ SourceKit.Generators.Grpc/SourceKit.Generators.Grpc.Generators.ProtoMessageConstructorGenerator/Playground.ProtoModel.SourceKit.Generators.Grpc.g.cs
""",
Content: """
//
- // This code was generated by a SourceKit.Generators.Grpc code generator.
- // https://github.com/itmo-is-dev/SourceKit
+ // This code was generated by a SourceKit.Generators.Grpc code generator.
+ // https://github.com/itmo-is-dev/SourceKit
//
#pragma warning disable CS1591
using System;
@@ -665,7 +665,7 @@ namespace Playground
{
public partial class ProtoModel
{
- public ProtoModel(String? pageToken, IEnumerable values, Int32 pageSize, IEnumerable intValues, Int32? intOneofValue, String? stringOneofValue, String notNullStringValue, Nullable nullIntValue, String? nullStringValue, IEnumerable> mapValue)
+ public ProtoModel(string? pageToken, IEnumerable values, int pageSize, IEnumerable intValues, int? intOneofValue, string? stringOneofValue, string notNullStringValue, int? nullIntValue, string? nullStringValue, IEnumerable> mapValue)
{
PageToken = pageToken;
Values.Add(values);
@@ -684,7 +684,7 @@ public ProtoModel(String? pageToken, IEnumerable values, Int32 pageSize,
NotNullStringValue = notNullStringValue;
NullIntValue = nullIntValue;
NullStringValue = nullStringValue;
- foreach (KeyValuePair item in mapValue)
+ foreach (KeyValuePair item in mapValue)
{
MapValue.Add(item.Key, item.Value);
}