From 267aa40c01a722111d3d96d5402e8d6060243a73 Mon Sep 17 00:00:00 2001 From: Todd Lang Date: Thu, 9 Apr 2026 08:54:48 -0400 Subject: [PATCH 1/5] Sharing the constant analyzer between regular and test analyzers -Adding logic to support constant usages in test-only contexts (rhino mocks, for example) --- D2L.CodeStyle.sln | 31 +++++++- .../D2L.CodeStyle.Analyzers.csproj | 11 +++ .../D2L.CodeStyle.Annotations.csproj | 1 + .../D2L.CodeStyle.SpecTests.csproj | 3 +- .../D2L.CodeStyle.TestAnalyzers.csproj | 19 ++++- .../ConstantAttributeAnalyzer.cs | 73 +++++++++++++++++-- ...L.CodeStyle.Analyzers.Rule.Constant.csproj | 31 ++++++++ .../D2L.CodeStyle.Analyzers.Rule.csproj | 23 ++++++ .../Diagnostics.cs | 0 .../GlobalSuppressions.cs | 12 +++ .../ReportDiagnosticExtensions.cs | 4 +- .../D2L.CodeStyle.Analyzers.Tests.csproj | 3 + .../Specs/ConstantAttributeAnalyzer.cs | 4 +- .../D2L.CodeStyle.TestAnalyzers.Tests.csproj | 1 + 14 files changed, 204 insertions(+), 12 deletions(-) rename src/{D2L.CodeStyle.Analyzers/ApiUsage => Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant}/ConstantAttributeAnalyzer.cs (76%) create mode 100644 src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj create mode 100644 src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj rename src/{D2L.CodeStyle.Analyzers => Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule}/Diagnostics.cs (100%) create mode 100644 src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/GlobalSuppressions.cs rename src/{D2L.CodeStyle.Analyzers/Extensions => Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule}/ReportDiagnosticExtensions.cs (93%) diff --git a/D2L.CodeStyle.sln b/D2L.CodeStyle.sln index f1c91aba..eafd8ee7 100644 --- a/D2L.CodeStyle.sln +++ b/D2L.CodeStyle.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.32112.339 +# Visual Studio Version 18 +VisualStudioVersion = 18.5.11626.173 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "D2L.CodeStyle.Annotations", "src\D2L.CodeStyle.Annotations\D2L.CodeStyle.Annotations.csproj", "{1812AF7E-59B1-4764-8090-F84446A71C4E}" EndProject @@ -22,6 +22,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Directory.build.props = Directory.build.props EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D2L.CodeStyle.Analyzers.Rule.Constant", "src\Rules\D2L.CodeStyle.Analyzers.Rule.Constant\D2L.CodeStyle.Analyzers.Rule.Constant\D2L.CodeStyle.Analyzers.Rule.Constant.csproj", "{9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Rules", "Rules", "{1D7FCA55-CA25-4264-BB5D-331CF09C1A00}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "D2L.CodeStyle.Analyzers.Rule", "src\Rules\D2L.CodeStyle.Analyzers.Rule\D2L.CodeStyle.Analyzers.Rule\D2L.CodeStyle.Analyzers.Rule.csproj", "{04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Constant", "Constant", "{FE0449B9-2A7B-48DD-BBDB-B6A0FB19A2A9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -78,6 +86,22 @@ Global {C7B3A703-A549-48AA-90A6-A145C91D4F85}.Release|Any CPU.Build.0 = Release|Any CPU {C7B3A703-A549-48AA-90A6-A145C91D4F85}.Release|x86.ActiveCfg = Release|Any CPU {C7B3A703-A549-48AA-90A6-A145C91D4F85}.Release|x86.Build.0 = Release|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Debug|x86.ActiveCfg = Debug|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Debug|x86.Build.0 = Debug|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Release|Any CPU.Build.0 = Release|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Release|x86.ActiveCfg = Release|Any CPU + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9}.Release|x86.Build.0 = Release|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Debug|x86.ActiveCfg = Debug|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Debug|x86.Build.0 = Debug|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Release|Any CPU.Build.0 = Release|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Release|x86.ActiveCfg = Release|Any CPU + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -85,6 +109,9 @@ Global GlobalSection(NestedProjects) = preSolution {1C54E78A-E12B-45C3-BA6E-31DB5C63B389} = {3873E5AD-A61F-4CE4-B2E1-5AD83D25BF79} {2F10EDAF-8585-4B4C-A82A-BABC5D23A186} = {3873E5AD-A61F-4CE4-B2E1-5AD83D25BF79} + {9F66950B-83B2-4A9E-8C26-ABAC97E55CA9} = {FE0449B9-2A7B-48DD-BBDB-B6A0FB19A2A9} + {04534CAC-57B7-4462-BE31-D8C1C6B7BAA7} = {1D7FCA55-CA25-4264-BB5D-331CF09C1A00} + {FE0449B9-2A7B-48DD-BBDB-B6A0FB19A2A9} = {1D7FCA55-CA25-4264-BB5D-331CF09C1A00} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {B1068C74-1517-443E-99B8-CB4834D47628} diff --git a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj index 22a53545..5ce1207b 100644 --- a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj +++ b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj @@ -27,6 +27,8 @@ + + @@ -49,4 +51,13 @@ + + + all + + + all + + + diff --git a/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj b/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj index 330f5902..3f63cb31 100644 --- a/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj +++ b/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj @@ -2,6 +2,7 @@ net20;netstandard2.0 + false disable diff --git a/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj b/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj index 790fa362..47d02102 100644 --- a/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj +++ b/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj @@ -1,6 +1,7 @@ - + netstandard2.0 + false diff --git a/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj b/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj index fc80de0b..ac4930a1 100644 --- a/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj +++ b/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj @@ -6,7 +6,7 @@ D2L.CodeStyle.TestAnalyzers D2L.CodeStyle D2L.CodeStyle test analyzers - 0.29.0 + 0.29.11 Apache-2.0 https://github.com/Brightspace/D2L.CodeStyle D2L @@ -26,8 +26,16 @@ + + + + + + + + all @@ -41,4 +49,13 @@ + + + all + + + all + + + diff --git a/src/D2L.CodeStyle.Analyzers/ApiUsage/ConstantAttributeAnalyzer.cs b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/ConstantAttributeAnalyzer.cs similarity index 76% rename from src/D2L.CodeStyle.Analyzers/ApiUsage/ConstantAttributeAnalyzer.cs rename to src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/ConstantAttributeAnalyzer.cs index 79490eae..5d7c972f 100644 --- a/src/D2L.CodeStyle.Analyzers/ApiUsage/ConstantAttributeAnalyzer.cs +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/ConstantAttributeAnalyzer.cs @@ -10,6 +10,7 @@ namespace D2L.CodeStyle.Analyzers.ApiUsage { [DiagnosticAnalyzer( LanguageNames.CSharp )] public sealed class ConstantAttributeAnalyzer : DiagnosticAnalyzer { + public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create( Diagnostics.NonConstantPassedToConstantParameter, @@ -31,7 +32,7 @@ CompilationStartAnalysisContext context ); // The D2L.CodeStyle.Annotations reference is optional - if ( constantAttribute == null || constantAttribute .Kind == SymbolKind.ErrorType ) { + if( constantAttribute == null || constantAttribute.Kind == SymbolKind.ErrorType ) { return; } @@ -106,13 +107,13 @@ ISymbol constantAttribute if( type.Kind == SymbolKind.TypeParameter ) { return; } - + // The current parameter type cannot be marked as [Constant] context.ReportDiagnostic( descriptor: Diagnostics.InvalidConstantType, location: parameter.Locations.First(), messageArgs: new object[] { type.TypeKind } - ); + ); } private static void AnalyzeArgument( @@ -123,7 +124,7 @@ ISymbol constantAttribute var parameter = argument.Parameter; // Parameter is not [Constant], so do nothing - if( !HasAttribute( parameter, constantAttribute ) ) { + if( !HasAttribute( parameter, constantAttribute )) { return; } @@ -132,6 +133,16 @@ ISymbol constantAttribute return; } + // Argument is inside an expression tree (e.g. Moq Verify/Setup), so do nothing + if( IsInsideExpressionTree( argument ) ) { + return; + } + + // Argument is a mock argument constraint (e.g. Arg.Is.Anything), so do nothing + if( IsMockArgumentConstraint( argument.Value ) ) { + return; + } + // Argument was defined as [Constant] already, so trust it var argumentSymbol = argument.SemanticModel.GetSymbolInfo( argument.Value.Syntax, context.CancellationToken ).Symbol; if( argumentSymbol != null && HasAttribute( argumentSymbol, constantAttribute ) ) { @@ -161,7 +172,7 @@ INamedTypeSymbol constantAttribute } // Operator parameter is not [Constant], so do nothing - IParameterSymbol parameter = @operator.Parameters[ 0 ]; + IParameterSymbol parameter = @operator.Parameters[0]; if( !HasAttribute( parameter, constantAttribute ) ) { return; } @@ -258,6 +269,58 @@ ISymbol attributeSymbol ); } + private static bool IsInsideExpressionTree( IOperation operation ) { + IOperation current = operation; + while( current != null ) { + if( current is IConversionOperation conversion + && conversion.Type is INamedTypeSymbol namedType + && namedType.BaseType != null + && namedType.BaseType.Name == "LambdaExpression" + ) { + return true; + } + current = current.Parent; + } + return false; + } + + private static bool IsMockArgumentConstraint( IOperation operation ) { + // Matches patterns like Arg.Is.Anything or Arg.Is.Equal(...) (Rhino Mocks) + // Arg.Is.Anything is a property chain: Arg.Is (static) -> .Anything (instance) + // Arg.Is.Equal(...) is a method call on the .Is property result + if( operation is IInvocationOperation invocation ) { + var containingType = invocation.TargetMethod.ContainingType; + if( IsArgType( containingType ) ) { + return true; + } + // Check if the instance receiver is an Arg property chain + if( invocation.Instance != null && IsMockArgumentConstraint( invocation.Instance ) ) { + return true; + } + } + + IOperation current = operation; + while( current is IPropertyReferenceOperation propertyRef ) { + var containingType = propertyRef.Property.ContainingType; + if( IsArgType( containingType ) ) { + return true; + } + current = propertyRef.Instance; + } + return false; + } + + private static bool IsArgType( INamedTypeSymbol type ) { + if( type == null ) { + return false; + } + if( type.Name == "Arg" && type.IsGenericType ) { + return true; + } + // Check containing types for nested types within Arg + return IsArgType( type.ContainingType ); + } + private static bool IsStringEmpty( IOperation operation ) { if( operation is IFieldReferenceOperation fieldRef ) { return fieldRef.Field.ContainingType.SpecialType == SpecialType.System_String diff --git a/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj new file mode 100644 index 00000000..b17c3f0e --- /dev/null +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj @@ -0,0 +1,31 @@ + + + + netstandard2.0 + true + true + false + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj new file mode 100644 index 00000000..ba2a8210 --- /dev/null +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj @@ -0,0 +1,23 @@ + + + + netstandard2.0 + false + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/src/D2L.CodeStyle.Analyzers/Diagnostics.cs b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/Diagnostics.cs similarity index 100% rename from src/D2L.CodeStyle.Analyzers/Diagnostics.cs rename to src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/Diagnostics.cs diff --git a/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/GlobalSuppressions.cs b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/GlobalSuppressions.cs new file mode 100644 index 00000000..dded2a97 --- /dev/null +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/GlobalSuppressions.cs @@ -0,0 +1,12 @@ +// This file is used by Code Analysis to maintain SuppressMessage +// attributes that are applied to this project. +// Project-level suppressions either have no target or are given +// a specific target and scoped to a namespace, type, member, etc. + +using System.Diagnostics.CodeAnalysis; + +[assembly: SuppressMessage( + "MicrosoftCodeAnalysisReleaseTracking", + "RS2008:Enable analyzer release tracking", + Justification = "Not maintaing a releases file at this time." +)] diff --git a/src/D2L.CodeStyle.Analyzers/Extensions/ReportDiagnosticExtensions.cs b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/ReportDiagnosticExtensions.cs similarity index 93% rename from src/D2L.CodeStyle.Analyzers/Extensions/ReportDiagnosticExtensions.cs rename to src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/ReportDiagnosticExtensions.cs index 77feaf86..128cc544 100644 --- a/src/D2L.CodeStyle.Analyzers/Extensions/ReportDiagnosticExtensions.cs +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/ReportDiagnosticExtensions.cs @@ -2,7 +2,7 @@ namespace Microsoft.CodeAnalysis { - internal static class ReportDiagnosticExtensions { + public static class ReportDiagnosticExtensions { public static void ReportDiagnostic( this SourceProductionContext context, @@ -28,7 +28,7 @@ public static void ReportDiagnostic( namespace Microsoft.CodeAnalysis.Diagnostics { - internal static class ReportDiagnosticExtensions { + public static class ReportDiagnosticExtensions { public static void ReportDiagnostic( this CompilationAnalysisContext context, diff --git a/tests/D2L.CodeStyle.Analyzers.Test/D2L.CodeStyle.Analyzers.Tests.csproj b/tests/D2L.CodeStyle.Analyzers.Test/D2L.CodeStyle.Analyzers.Tests.csproj index 0722e33f..f699d725 100644 --- a/tests/D2L.CodeStyle.Analyzers.Test/D2L.CodeStyle.Analyzers.Tests.csproj +++ b/tests/D2L.CodeStyle.Analyzers.Test/D2L.CodeStyle.Analyzers.Tests.csproj @@ -1,6 +1,7 @@  net48 + false @@ -16,6 +17,8 @@ + + diff --git a/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs b/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs index bc39f0af..34d9ad17 100644 --- a/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs +++ b/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs @@ -1,6 +1,7 @@ -// analyzer: D2L.CodeStyle.Analyzers.ApiUsage.ConstantAttributeAnalyzer, D2L.CodeStyle.Analyzers +// analyzer: D2L.CodeStyle.Analyzers.ApiUsage.ConstantAttributeAnalyzer, D2L.CodeStyle.Analyzers.Rule.Constant using System; +using D2L.Core; namespace SpecTests { @@ -91,6 +92,7 @@ void Method() { #region String tests string variableStr = "This is a variable message"; const string CONSTANT_STR = "This is a constant message"; + ConstantString constantStr = "This is a constant string message"; Types.SomeMethodWithConstantParameter( "This is a constant message" ); Types.SomeMethodWithConstantParameter( CONSTANT_STR ); diff --git a/tests/D2L.CodeStyle.TestAnalyzers.Tests/D2L.CodeStyle.TestAnalyzers.Tests.csproj b/tests/D2L.CodeStyle.TestAnalyzers.Tests/D2L.CodeStyle.TestAnalyzers.Tests.csproj index 1b993201..7dbfb0a3 100644 --- a/tests/D2L.CodeStyle.TestAnalyzers.Tests/D2L.CodeStyle.TestAnalyzers.Tests.csproj +++ b/tests/D2L.CodeStyle.TestAnalyzers.Tests/D2L.CodeStyle.TestAnalyzers.Tests.csproj @@ -1,6 +1,7 @@  net48 + false From eec2eb40dd458096a56215fc80dff7454acdec50 Mon Sep 17 00:00:00 2001 From: Todd Lang Date: Thu, 16 Jul 2026 10:32:07 -0400 Subject: [PATCH 2/5] Minor cleanups to reduce changes --- .../D2L.CodeStyle.Annotations.csproj | 1 - src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj | 1 - .../D2L.CodeStyle.TestAnalyzers.csproj | 2 +- .../ConstantAttributeAnalyzer.cs | 4 ++-- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj b/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj index 3f63cb31..330f5902 100644 --- a/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj +++ b/src/D2L.CodeStyle.Annotations/D2L.CodeStyle.Annotations.csproj @@ -2,7 +2,6 @@ net20;netstandard2.0 - false disable diff --git a/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj b/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj index 47d02102..9a804523 100644 --- a/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj +++ b/src/D2L.CodeStyle.SpecTests/D2L.CodeStyle.SpecTests.csproj @@ -1,7 +1,6 @@  netstandard2.0 - false diff --git a/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj b/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj index ac4930a1..99926db1 100644 --- a/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj +++ b/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj @@ -6,7 +6,7 @@ D2L.CodeStyle.TestAnalyzers D2L.CodeStyle D2L.CodeStyle test analyzers - 0.29.11 + 0.30.0 Apache-2.0 https://github.com/Brightspace/D2L.CodeStyle D2L diff --git a/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/ConstantAttributeAnalyzer.cs b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/ConstantAttributeAnalyzer.cs index 5d7c972f..942b2359 100644 --- a/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/ConstantAttributeAnalyzer.cs +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/ConstantAttributeAnalyzer.cs @@ -107,13 +107,13 @@ ISymbol constantAttribute if( type.Kind == SymbolKind.TypeParameter ) { return; } - + // The current parameter type cannot be marked as [Constant] context.ReportDiagnostic( descriptor: Diagnostics.InvalidConstantType, location: parameter.Locations.First(), messageArgs: new object[] { type.TypeKind } - ); + ); } private static void AnalyzeArgument( From fa1a7b718d39050bcc849e403f75574da069ed5c Mon Sep 17 00:00:00 2001 From: Todd Lang Date: Thu, 16 Jul 2026 12:49:41 -0400 Subject: [PATCH 3/5] Cleaning up whitespace in csproj files -Removing D2L.Core addition and ConstantString reference in spec tests --- .../D2L.CodeStyle.Analyzers.csproj | 16 +++--- .../D2L.CodeStyle.TestAnalyzers.csproj | 20 ++++---- ...L.CodeStyle.Analyzers.Rule.Constant.csproj | 50 +++++++++---------- .../D2L.CodeStyle.Analyzers.Rule.csproj | 34 ++++++------- .../Specs/ConstantAttributeAnalyzer.cs | 2 - 5 files changed, 60 insertions(+), 62 deletions(-) diff --git a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj index 5ce1207b..fa7abe47 100644 --- a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj +++ b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj @@ -27,8 +27,8 @@ - - + + @@ -52,12 +52,12 @@ - - all - - - all - + + all + + + all + diff --git a/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj b/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj index 99926db1..9458317a 100644 --- a/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj +++ b/src/D2L.CodeStyle.TestAnalyzers/D2L.CodeStyle.TestAnalyzers.csproj @@ -27,7 +27,7 @@ - + @@ -35,7 +35,7 @@ - + all @@ -49,13 +49,13 @@ - - - all - - - all - - + + + all + + + all + + diff --git a/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj index b17c3f0e..c48bb3e7 100644 --- a/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant/D2L.CodeStyle.Analyzers.Rule.Constant.csproj @@ -1,31 +1,31 @@  - - netstandard2.0 - true - true - false - + + netstandard2.0 + true + true + false + - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + - - - + + + diff --git a/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj index ba2a8210..404aae11 100644 --- a/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj +++ b/src/Rules/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule/D2L.CodeStyle.Analyzers.Rule.csproj @@ -2,22 +2,22 @@ netstandard2.0 - false + false - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + diff --git a/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs b/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs index 34d9ad17..08655493 100644 --- a/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs +++ b/tests/D2L.CodeStyle.Analyzers.Test/Specs/ConstantAttributeAnalyzer.cs @@ -1,7 +1,6 @@ // analyzer: D2L.CodeStyle.Analyzers.ApiUsage.ConstantAttributeAnalyzer, D2L.CodeStyle.Analyzers.Rule.Constant using System; -using D2L.Core; namespace SpecTests { @@ -92,7 +91,6 @@ void Method() { #region String tests string variableStr = "This is a variable message"; const string CONSTANT_STR = "This is a constant message"; - ConstantString constantStr = "This is a constant string message"; Types.SomeMethodWithConstantParameter( "This is a constant message" ); Types.SomeMethodWithConstantParameter( CONSTANT_STR ); From 53e5f30981a17ba6af1fad60a107dce57565694f Mon Sep 17 00:00:00 2001 From: Todd Lang Date: Thu, 16 Jul 2026 12:59:11 -0400 Subject: [PATCH 4/5] Add missing file copy validators --- src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj index fa7abe47..e70c9739 100644 --- a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj +++ b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj @@ -30,6 +30,11 @@ + + + + + all From 03e40c8c5770675e7d5a5a03e14c862efdf0c883 Mon Sep 17 00:00:00 2001 From: Todd Lang Date: Thu, 16 Jul 2026 13:02:40 -0400 Subject: [PATCH 5/5] Updating test analyzer version --- src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj index e70c9739..48d1e0ce 100644 --- a/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj +++ b/src/D2L.CodeStyle.Analyzers/D2L.CodeStyle.Analyzers.csproj @@ -6,7 +6,7 @@ D2L.CodeStyle.Analyzers D2L.CodeStyle D2L.CodeStyle analyzers - 0.223.0 + 0.224.0 Apache-2.0 https://github.com/Brightspace/D2L.CodeStyle D2L