From dba9c99a5d95bae574cbf1e5205701cf0b2eb2b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 20 Mar 2020 11:09:07 +0100 Subject: [PATCH 1/2] CA1070: Do not use mutable struct in readonly field --- .../DoNotUseMutableStructInReadonlyField.cs | 62 ++++++++++ ...icrosoftCodeQualityAnalyzersResources.resx | 9 ++ ...rosoftCodeQualityAnalyzersResources.cs.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.de.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.es.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.fr.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.it.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.ja.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.ko.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.pl.xlf | 15 +++ ...oftCodeQualityAnalyzersResources.pt-BR.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.ru.xlf | 15 +++ ...rosoftCodeQualityAnalyzersResources.tr.xlf | 15 +++ ...tCodeQualityAnalyzersResources.zh-Hans.xlf | 15 +++ ...tCodeQualityAnalyzersResources.zh-Hant.xlf | 15 +++ ...NotUseMutableStructInReadonlyFieldTests.cs | 109 ++++++++++++++++++ src/Utilities/Compiler/WellKnownTypeNames.cs | 5 + 17 files changed, 380 insertions(+) create mode 100644 src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyField.cs create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyFieldTests.cs diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyField.cs b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyField.cs new file mode 100644 index 0000000000..01f268ee87 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyField.cs @@ -0,0 +1,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 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); + }); + } + } +} diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx index e8c8cfcd31..226166b9f0 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/MicrosoftCodeQualityAnalyzersResources.resx @@ -1370,4 +1370,13 @@ Enums values should not be duplicated + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + Do not use mutable struct in readonly field + + + Do not use mutable struct in readonly field + \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf index 464e296884..2fd8380320 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.cs.xlf @@ -142,6 +142,21 @@ Neukládejte asynchronní výrazy lambda jako typy delegátů vracející hodnotu Void. + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. Odkaz na pole {0} je v této bitové inicializaci duplicitní. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf index 7c20c397e0..a6b8891a2c 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.de.xlf @@ -142,6 +142,21 @@ Async-Lambdas nicht als "Void" zurückgebende Delegattypen speichern + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. Der Feldverweis "{0}" wird in dieser bitweisen Initialisierung dupliziert. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf index 82299e4e70..2a9f736d12 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.es.xlf @@ -142,6 +142,21 @@ No almacenar expresiones lambda asincrónicas como void que devuelve tipos de delegado + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. La referencia de campo "{0}" está duplicada en esta inicialización bit a bit. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf index 1cd9046036..5736cdac43 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.fr.xlf @@ -142,6 +142,21 @@ Ne pas stocker de lambdas asynchrones en tant que types délégués retournant void + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. La référence de champ '{0}' est dupliquée dans cette initialisation au niveau du bit. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf index c5015f1927..d5c234841f 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.it.xlf @@ -142,6 +142,21 @@ Non archiviare espressioni lambda asincrone come tipi delegati che restituiscono void + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. Il riferimento al campo '{0}' è duplicato in questa inizializzazione bit per bit. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf index 06e0ec3144..424fcbd874 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ja.xlf @@ -142,6 +142,21 @@ デリゲート型を返す Void として非同期ラムダを格納しないでください + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. フィールド参照 '{0}' は、このビット単位の初期化で重複しています。 diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf index 9c2560e6be..d5dc6a7032 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ko.xlf @@ -142,6 +142,21 @@ 비동기 람다를 Void 반환 대리자 형식으로 저장하지 마세요. + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. 이 비트 초기화에서 필드 참조 '{0}'이(가) 중복되었습니다. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf index 840a795d50..c67349bb59 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pl.xlf @@ -142,6 +142,21 @@ Nie przechowuj asynchronicznych wyrażeń lambda jako typów delegatów zwracających typ void + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. Odwołanie do pola „{0}” jest zduplikowane w tym inicjowaniu bitowym. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf index 26f1354d8c..99c4b8745e 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.pt-BR.xlf @@ -142,6 +142,21 @@ Não armazenar lambdas assíncronas como tipos delegados que retornam void + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. A referência de campo '{0}' está duplicada nesta inicialização bit a bit. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf index ca704cda36..c4edcdb3ca 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.ru.xlf @@ -142,6 +142,21 @@ Не храните асинхронные лямбда-выражения как Void, возвращающие типы делегатов + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. Ссылка на поле "{0}" дублируется в этой побитовой инициализации. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf index 4e4a912123..0e0b53de2b 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.tr.xlf @@ -142,6 +142,21 @@ Temsilci Türlerini Döndüren Void Olarak Async Lambdaları Depolamayın + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. '{0}' alan başvurusu bu bit düzeyinde başlatmada yineleniyor. diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf index d9bfe7a098..294a55101e 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hans.xlf @@ -142,6 +142,21 @@ 不要将异步 Lambda 作为 Void 返回委托类型存储 + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. 此按位初始化中的字段引用 "{0}" 重复。 diff --git a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf index b81d094644..f54d2043cd 100644 --- a/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.CodeQuality.Analyzers/xlf/MicrosoftCodeQualityAnalyzersResources.zh-Hant.xlf @@ -142,6 +142,21 @@ 請勿將 Async Lambdas 儲存為 Void 傳回委派類型 + + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + Making a mutable struct a readonly field can result in silent but significant problems as any mutatin to the instance will be done on a compiler-generated copy and thus ignored. + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + + + Do not use mutable struct in readonly field + Do not use mutable struct in readonly field + + The field reference '{0}' is duplicated in this bitwise initialization. 欄位參考 '{0}' 在此位元初始化中重複。 diff --git a/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyFieldTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyFieldTests.cs new file mode 100644 index 0000000000..e3e2fbcda0 --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.CodeQuality.Analyzers/ApiDesignGuidelines/DoNotUseMutableStructInReadonlyFieldTests.cs @@ -0,0 +1,109 @@ +// 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.Threading.Tasks; +using Microsoft.CodeAnalysis.Testing; +using Microsoft.CodeAnalysis.VisualBasic.Syntax; +using Xunit; +using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< + Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.DoNotUseMutableStructInReadonlyField, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; +using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< + Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.DoNotUseMutableStructInReadonlyField, + Microsoft.CodeAnalysis.Testing.EmptyCodeFixProvider>; + +namespace Microsoft.CodeQuality.Analyzers.ApiDesignGuidelines.UnitTests +{ + public class DoNotUseMutableStructInReadonlyFieldTests + { + [Theory] + [InlineData("System.Threading.SpinLock")] + [InlineData("System.Runtime.InteropServices.GCHandle")] + public async Task CA1070_KnownMutableStruct_Diagnostic(string mutableType) + { + await VerifyCS.VerifyAnalyzerAsync($@" +public class Class1 +{{ + public readonly {mutableType} publicField; + private readonly {mutableType} privateField; +}} + +public struct Struct1 +{{ + public readonly {mutableType} publicField; + private readonly {mutableType} privateField; +}}", + GetCSharpResultAt(4, 22 + mutableType.Length), + GetCSharpResultAt(5, 23 + mutableType.Length), + GetCSharpResultAt(10, 22 + mutableType.Length), + GetCSharpResultAt(11, 23 + mutableType.Length)); + + await VerifyVB.VerifyAnalyzerAsync($@" +Public Class Class1 + Public ReadOnly publicField As {mutableType} + Private ReadOnly privateField As {mutableType} +End Class + +Public Structure Struct1 + Public ReadOnly publicField As {mutableType} + Private ReadOnly privateField As {mutableType} +End Structure", + GetBasicResultAt(3, 21), + GetBasicResultAt(4, 22), + GetBasicResultAt(8, 21), + GetBasicResultAt(9, 22)); + } + + [Fact] + public async Task CA1070_OtherStruct_NoDiagnostic() + { + await VerifyCS.VerifyAnalyzerAsync(@" +public class Class1 +{ + public readonly int publicInt; + private readonly int privateInt; + + public readonly Shape publicStruct; + private readonly Shape privateStruct; +} + +public struct Struct1 +{ + public readonly int publicInt; + private readonly int privateInt; + + public readonly Shape publicStruct; + private readonly Shape privateStruct; +} + +public struct Shape {}"); + + await VerifyVB.VerifyAnalyzerAsync(@" +Public Class Class1 + Public ReadOnly publicInt As Integer + Private ReadOnly privateInt As Integer + + Public ReadOnly publicStruct As Shape + Private ReadOnly privateStruct As Shape +End Class + +Public Structure Struct1 + Public ReadOnly publicInt As Integer + Private ReadOnly privateInt As Integer + + Public ReadOnly publicStruct As Shape + Private ReadOnly privateStruct As Shape +End Structure + +Public Structure Shape +End Structure"); + } + + private static DiagnosticResult GetCSharpResultAt(int line, int column) + => VerifyCS.Diagnostic() + .WithLocation(line, column); + + private static DiagnosticResult GetBasicResultAt(int line, int column) + => VerifyVB.Diagnostic() + .WithLocation(line, column); + } +} diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index 3f24593084..ae52e952f9 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -1,5 +1,8 @@ // 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; +using System.Runtime.CompilerServices; + namespace Analyzer.Utilities { internal static class WellKnownTypeNames @@ -488,5 +491,7 @@ internal static class WellKnownTypeNames public const string SystemCollectionsObjectModelReadOnlyDictionary2 = "System.Collections.ObjectModel.ReadOnlyDictionary`2"; public const string SystemCollectionsObjectModelReadOnlyObservableCollection1 = "System.Collections.ObjectModel.ReadOnlyObservableCollection`1"; public const string RoslynUtilitiesNonDefaultableAttribute = "Roslyn.Utilities.NonDefaultableAttribute"; + public const string SystemThreadingSpinLock = "System.Threading.SpinLock"; + public const string SystemRuntimeInteropServicesGCHandle = "System.Runtime.InteropServices.GCHandle"; } } From 345fa15617c8c531d3cdc2ac0ef29fabaf33ab9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaury=20Lev=C3=A9?= Date: Fri, 20 Mar 2020 11:11:09 +0100 Subject: [PATCH 2/2] Remove un-needed usings --- src/Utilities/Compiler/WellKnownTypeNames.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index ae52e952f9..b50f0280ad 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -1,8 +1,5 @@ // 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; -using System.Runtime.CompilerServices; - namespace Analyzer.Utilities { internal static class WellKnownTypeNames