forked from dotnet/roslyn-analyzers
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDoNotUseMutableStructInReadonlyField.cs
62 lines (52 loc) · 3.21 KB
/
DoNotUseMutableStructInReadonlyField.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Collections.Immutable;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Diagnostics;
using Analyzer.Utilities;
using Analyzer.Utilities.Extensions;
namespace Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines
{
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public sealed class DoNotUseMutableStructInReadonlyField : DiagnosticAnalyzer
{
internal const string RuleId = "CA1070";
private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.DoNotUseMutableStructInReadonlyFieldTitle), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources));
private static readonly LocalizableString s_localizableMessage = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.DoNotUseMutableStructInReadonlyFieldMessage), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources));
private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(MicrosoftCodeQualityAnalyzersResources.DoNotUseMutableStructInReadonlyFieldDescription), MicrosoftCodeQualityAnalyzersResources.ResourceManager, typeof(MicrosoftCodeQualityAnalyzersResources));
internal static DiagnosticDescriptor Rule =
DiagnosticDescriptorHelper.Create(
RuleId,
s_localizableTitle,
s_localizableMessage,
DiagnosticCategory.Design,
RuleLevel.BuildWarningCandidate,
s_localizableDescription,
isPortedFxCopRule: true,
isDataflowRule: false);
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics { get; } = ImmutableArray.Create(Rule);
public override void Initialize(AnalysisContext analysisContext)
{
analysisContext.EnableConcurrentExecution();
analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);
analysisContext.RegisterCompilationStartAction(context =>
{
var spinLockType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingSpinLock);
var gcHandleType = context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemRuntimeInteropServicesGCHandle);
context.RegisterSymbolAction(context =>
{
var field = (IFieldSymbol)context.Symbol;
if (!field.IsReadOnly ||
field.Type?.TypeKind != TypeKind.Struct)
{
return;
}
if (field.Type.Equals(spinLockType) ||
field.Type.Equals(gcHandleType))
{
context.ReportDiagnostic(field.CreateDiagnostic(Rule));
}
}, SymbolKind.Field);
});
}
}
}