Skip to content

Commit

Permalink
Enable RS1038 unless .globalconfig provides:
Browse files Browse the repository at this point in the history
roslyn_correctness.assembly_reference_validation = relaxed
  • Loading branch information
sharwell committed Jun 22, 2023
1 parent f9e4348 commit cc316f3
Show file tree
Hide file tree
Showing 9 changed files with 211 additions and 58 deletions.
8 changes: 7 additions & 1 deletion docs/rules/RS1022.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Diagnostic analyzer types should not use types from Workspaces assemblies. Works
|Item|Value|
|-|-|
|Category|MicrosoftCodeAnalysisCorrectness|
|Enabled|False|
|Enabled|True|
|Severity|Warning|
|CodeFix|False|
---
Expand All @@ -14,3 +14,9 @@ Diagnostic analyzer types should not use types from Workspaces assemblies. Works
>
> The analysis performed by RS1022 is slow and relies on implementation details of the JIT compiler for correctness.
> Authors of compiler extensions are encouraged to use the stricter (and faster) analyzer RS1038 instead of this rule.
>
> RS1038 is enabled by default. To enable RS1022 instead, the following configuration may be added to **.globalconfig**:
>
> ```ini
> roslyn_correctness.assembly_reference_validation = relaxed
> ```
3 changes: 3 additions & 0 deletions docs/rules/RS1038.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ scenarios. Depending on the manner in which the compiler is invoked, some assemb
and attempting to reference them will result in exceptions that prevent the compiler extension from loading. RS1038 is
the most strict and best performing validation for this scenario.

RS1038 is enabled by default unless relaxed validation has been manually enabled in **.globalconfig** as described in
[RS1022](RS1022.md).

### Rules for compiler feature references

* Compiler features supporting C# code should only reference the NuGet packages **Microsoft.CodeAnalysis.Common** and/or **Microsoft.CodeAnalysis.CSharp**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,3 @@
Rule ID | Category | Severity | Notes
--------|----------|----------|-------
RS1038 | MicrosoftCodeAnalysisCorrectness | Warning | CompilerExtensionStrictApiAnalyzer

### Changed Rules

Rule ID | New Category | New Severity | Old Category | Old Severity | Notes
--------|--------------|--------------|--------------|--------------|-------
RS1022 | MicrosoftCodeAnalysisCorrectness | Disabled | MicrosoftCodeAnalysisCorrectness | Warning | DiagnosticAnalyzerApiUsageAnalyzer
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.

using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -14,6 +15,9 @@ namespace Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
internal sealed class CompilerExtensionStrictApiAnalyzer : DiagnosticAnalyzer
{
private const string AssemblyReferenceValidationConfigurationKey = "roslyn_correctness.assembly_reference_validation";
private const string AssemblyReferenceValidationConfigurationRelaxedValue = "relaxed";

private static readonly LocalizableString s_localizableTitle = CreateLocalizableResourceString(nameof(DoNotRegisterCompilerTypesWithBadAssemblyReferenceRuleTitle));
private static readonly LocalizableString s_localizableDescription = CreateLocalizableResourceString(nameof(DoNotRegisterCompilerTypesWithBadAssemblyReferenceRuleDescription));
private const string HelpLinkUri = "https://github.com/dotnet/roslyn-analyzers/blob/main/docs/rules/RS1038.md";
Expand Down Expand Up @@ -56,13 +60,29 @@ internal sealed class CompilerExtensionStrictApiAnalyzer : DiagnosticAnalyzer
DoNotDeclareCSharpCompilerFeatureInAssemblyWithVisualBasicReferenceStrictRule,
DoNotDeclareVisualBasicCompilerFeatureInAssemblyWithCSharpReferenceStrictRule);

internal static bool IsStrictAnalysisEnabled(AnalyzerOptions options)
{
return !options.AnalyzerConfigOptionsProvider.GlobalOptions.TryGetValue(AssemblyReferenceValidationConfigurationKey, out var value)
|| !value.Trim().Equals(AssemblyReferenceValidationConfigurationRelaxedValue, StringComparison.Ordinal);
}

public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);

context.RegisterCompilationStartAction(context =>
{
// This analyzer is enabled by default via a configuration option that also applies to RS1022. It needs
// to proceed unless .globalconfig contains the following line to enable it:
//
// roslyn_correctness.assembly_reference_validation = relaxed
if (!IsStrictAnalysisEnabled(context.Options))
{
// RS1022 is being applied instead of RS1038
return;
}
var typeProvider = WellKnownTypeProvider.GetOrCreate(context.Compilation);
var diagnosticAnalyzer = typeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftCodeAnalysisDiagnosticsDiagnosticAnalyzer);
if (diagnosticAnalyzer is null)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information.

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
Expand Down Expand Up @@ -38,7 +39,7 @@ public abstract class DiagnosticAnalyzerApiUsageAnalyzer<TTypeSyntax> : Diagnost
CreateLocalizableResourceString(nameof(DoNotUseTypesFromAssemblyRuleDirectMessage)),
DiagnosticCategory.MicrosoftCodeAnalysisCorrectness,
DiagnosticSeverity.Warning,
isEnabledByDefault: false,
isEnabledByDefault: true,
description: s_localizableDescription,
helpLinkUri: HelpLinkUri,
customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry);
Expand All @@ -49,7 +50,7 @@ public abstract class DiagnosticAnalyzerApiUsageAnalyzer<TTypeSyntax> : Diagnost
CreateLocalizableResourceString(nameof(DoNotUseTypesFromAssemblyRuleIndirectMessage)),
DiagnosticCategory.MicrosoftCodeAnalysisCorrectness,
DiagnosticSeverity.Warning,
isEnabledByDefault: false,
isEnabledByDefault: true,
description: s_localizableDescription,
helpLinkUri: HelpLinkUri,
customTags: WellKnownDiagnosticTagsExtensions.CompilationEndAndTelemetry);
Expand All @@ -64,6 +65,16 @@ public override void Initialize(AnalysisContext context)

context.RegisterCompilationStartAction(compilationStartContext =>
{
// This analyzer is disabled by default via a configuration option that also applies to RS1038. It only
// needs to proceed if .globalconfig contains the following line to enable it:
//
// roslyn_correctness.assembly_reference_validation = relaxed
if (CompilerExtensionStrictApiAnalyzer.IsStrictAnalysisEnabled(compilationStartContext.Options))
{
// RS1038 is being applied instead of RS1022
return;
}
if (compilationStartContext.Compilation.GetOrCreateTypeByMetadataName(CodeActionMetadataName) == null)
{
// No reference to core Workspaces assembly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -275,7 +275,7 @@ Diagnostic analyzer types should not use types from Workspaces assemblies. Works
|Item|Value|
|-|-|
|Category|MicrosoftCodeAnalysisCorrectness|
|Enabled|False|
|Enabled|True|
|Severity|Warning|
|CodeFix|False|
---
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -806,7 +806,7 @@
"helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/main/docs/rules/RS1022.md",
"properties": {
"category": "MicrosoftCodeAnalysisCorrectness",
"isEnabledByDefault": false,
"isEnabledByDefault": true,
"typeName": "CSharpDiagnosticAnalyzerApiUsageAnalyzer",
"languages": [
"C#"
Expand Down Expand Up @@ -1005,7 +1005,7 @@
"helpUri": "https://github.com/dotnet/roslyn-analyzers/blob/main/docs/rules/RS1022.md",
"properties": {
"category": "MicrosoftCodeAnalysisCorrectness",
"isEnabledByDefault": false,
"isEnabledByDefault": true,
"typeName": "BasicDiagnosticAnalyzerApiUsageAnalyzer",
"languages": [
"Visual Basic"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,18 +73,31 @@ public async Task CSharpFeatureDefinedWithMatchingLanguageReference(CompilerFeat

[Theory]
[CombinatorialData]
public async Task CSharpFeatureDefinedWithWorkspaceReference(CompilerFeature feature, SupportedLanguage supportedLanguage)
public async Task CSharpFeatureDefinedWithWorkspaceReference(CompilerFeature feature, SupportedLanguage supportedLanguage, bool relaxedValidation)
{
await new VerifyCS.Test
var test = new VerifyCS.Test
{
ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard20.AddPackages(ImmutableArray.Create(
new PackageIdentity("Microsoft.CodeAnalysis.Workspaces.Common", CompilerReferenceVersion))),
TestCode = DefineFeature(ImplementationLanguage.CSharp, feature, supportedLanguage),
ExpectedDiagnostics =
{
VerifyCS.Diagnostic(CompilerExtensionStrictApiAnalyzer.DoNotDeclareCompilerFeatureInAssemblyWithWorkspacesReferenceStrictRule).WithLocation(0),
},
}.RunAsync();
};

if (relaxedValidation)
{
test.TestState.AnalyzerConfigFiles.Add(
("/.globalconfig",
"""
is_global = true

roslyn_correctness.assembly_reference_validation = relaxed
"""));
}
else
{
test.TestState.ExpectedDiagnostics.Add(VerifyCS.Diagnostic(CompilerExtensionStrictApiAnalyzer.DoNotDeclareCompilerFeatureInAssemblyWithWorkspacesReferenceStrictRule).WithLocation(0));
}

await test.RunAsync();
}

[Theory]
Expand Down Expand Up @@ -144,18 +157,31 @@ public async Task VisualBasicFeatureDefinedWithMatchingLanguageReference(Compile

[Theory]
[CombinatorialData]
public async Task VisualBasicFeatureDefinedWithWorkspaceReference(CompilerFeature feature, SupportedLanguage supportedLanguage)
public async Task VisualBasicFeatureDefinedWithWorkspaceReference(CompilerFeature feature, SupportedLanguage supportedLanguage, bool relaxedValidation)
{
await new VerifyVB.Test
var test = new VerifyVB.Test
{
ReferenceAssemblies = ReferenceAssemblies.NetStandard.NetStandard20.AddPackages(ImmutableArray.Create(
new PackageIdentity("Microsoft.CodeAnalysis.Workspaces.Common", CompilerReferenceVersion))),
TestCode = DefineFeature(ImplementationLanguage.VisualBasic, feature, supportedLanguage),
ExpectedDiagnostics =
{
VerifyVB.Diagnostic(CompilerExtensionStrictApiAnalyzer.DoNotDeclareCompilerFeatureInAssemblyWithWorkspacesReferenceStrictRule).WithLocation(0),
},
}.RunAsync();
};

if (relaxedValidation)
{
test.TestState.AnalyzerConfigFiles.Add(
("/.globalconfig",
"""
is_global = true

roslyn_correctness.assembly_reference_validation = relaxed
"""));
}
else
{
test.TestState.ExpectedDiagnostics.Add(VerifyVB.Diagnostic(CompilerExtensionStrictApiAnalyzer.DoNotDeclareCompilerFeatureInAssemblyWithWorkspacesReferenceStrictRule).WithLocation(0));
}

await test.RunAsync();
}

[Theory]
Expand Down
Loading

0 comments on commit cc316f3

Please sign in to comment.