From 955b243850222c0b79dcfddb8acd8977af9d0e5d Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Sun, 19 Nov 2023 12:22:47 +0100 Subject: [PATCH 01/10] Add UseVolatileReadWriteAnalyzer --- .../Usage/CSharpUseVolatileReadWriteFixer.cs | 28 ++ .../Core/AnalyzerReleases.Unshipped.md | 1 + .../MicrosoftNetCoreAnalyzersResources.resx | 18 + .../Usage/UseVolatileReadWrite.Fixer.cs | 56 +++ .../Usage/UseVolatileReadWrite.cs | 82 +++++ .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.de.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.es.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.it.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 30 ++ ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 30 ++ .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 30 ++ ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 30 ++ ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 30 ++ .../Microsoft.CodeAnalysis.NetAnalyzers.md | 12 + .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 20 + src/NetAnalyzers/RulesMissingDocumentation.md | 9 +- .../Usage/UseVolatileReadWriteTests.cs | 347 ++++++++++++++++++ .../Usage/BasicUseVolatileReadWriteFixer.vb | 27 ++ .../DiagnosticCategoryAndIdRanges.txt | 2 +- 24 files changed, 983 insertions(+), 9 deletions(-) create mode 100644 src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs create mode 100644 src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs create mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs create mode 100644 src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs new file mode 100644 index 0000000000..09da3e89d9 --- /dev/null +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Composition; +using System.Diagnostics.CodeAnalysis; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.NetCore.Analyzers.Usage; + +namespace Microsoft.NetCore.CSharp.Analyzers.Usage +{ + [ExportCodeFixProvider(LanguageNames.CSharp), Shared] + internal sealed class CSharpUseVolatileReadWriteFixer : UseVolatileReadWriteFixer + { + protected override bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess) + { + memberAccess = null; + if (invocation is InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax m } && m.Name.Identifier.Text == methodName) + { + memberAccess = m; + + return true; + } + + return false; + } + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index 460ef787ac..a308cb6feb 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -7,3 +7,4 @@ Rule ID | Category | Severity | Notes CA1514 | Maintainability | Info | AvoidLengthCheckWhenSlicingToEndAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1514) CA1515 | Maintainability | Disabled | MakeTypesInternal, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1515) CA2262 | Usage | Info | ProvideHttpClientHandlerMaxResponseHeaderLengthValueCorrectly, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2262) +CA2263 | Usage | Warning | UseVolatileReadWriteAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2263) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 979f75ff53..7ccd4c6aed 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -2096,4 +2096,22 @@ Widening and user defined conversions are not supported with generic types. Cache and reuse 'JsonSerializerOptions' instances + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + Use 'Volatile.Read' + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + Use 'Volatile.Write' + \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs new file mode 100644 index 0000000000..9778c70dc1 --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs @@ -0,0 +1,56 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Diagnostics.CodeAnalysis; +using System.Threading; +using System.Threading.Tasks; +using Analyzer.Utilities; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Editing; + +namespace Microsoft.NetCore.Analyzers.Usage +{ + public abstract class UseVolatileReadWriteFixer : CodeFixProvider + { + public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + var root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + var node = root.FindNode(context.Span, getInnermostNodeForTie: true); + if (TryGetThreadVolatileReadWriteMemberAccess(node, UseVolatileReadWriteAnalyzer.ThreadVolatileReadMethodName, out var readAccess)) + { + var codeAction = CodeAction.Create( + MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle, + _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(readAccess, CreateVolatileMemberAccess(context.Document, UseVolatileReadWriteAnalyzer.VolatileReadMethodName)))), + MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle + ); + context.RegisterCodeFix(codeAction, context.Diagnostics); + } + else if (TryGetThreadVolatileReadWriteMemberAccess(node, UseVolatileReadWriteAnalyzer.ThreadVolatileWriteMethodName, out var writeAccess)) + { + var codeAction = CodeAction.Create( + MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle, + _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(writeAccess, CreateVolatileMemberAccess(context.Document, UseVolatileReadWriteAnalyzer.VolatileWriteMethodName)))), + MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle + ); + context.RegisterCodeFix(codeAction, context.Diagnostics); + } + } + + private static SyntaxNode CreateVolatileMemberAccess(Document document, string methodName) + { + var generator = SyntaxGenerator.GetGenerator(document); + return generator.MemberAccessExpression( + generator.IdentifierName(nameof(Volatile)), + generator.IdentifierName(methodName) + ); + } + + public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + + protected abstract bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess); + + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create("CA2263"); + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs new file mode 100644 index 0000000000..ae77483a0e --- /dev/null +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs @@ -0,0 +1,82 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Collections.Immutable; +using System.Threading; +using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; + +namespace Microsoft.NetCore.Analyzers.Usage +{ + using static MicrosoftNetCoreAnalyzersResources; + + [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] + public sealed class UseVolatileReadWriteAnalyzer : DiagnosticAnalyzer + { + private const string RuleId = "CA2263"; + + internal const string ThreadVolatileReadMethodName = nameof(Thread.VolatileRead); + internal const string ThreadVolatileWriteMethodName = nameof(Thread.VolatileWrite); + internal const string VolatileReadMethodName = nameof(Volatile.Read); + internal const string VolatileWriteMethodName = nameof(Volatile.Write); + + internal static readonly DiagnosticDescriptor ReadDescriptor = DiagnosticDescriptorHelper.Create( + RuleId, + CreateLocalizableResourceString(nameof(UseVolatileReadTitle)), + CreateLocalizableResourceString(nameof(UseVolatileReadMessage)), + DiagnosticCategory.Usage, + RuleLevel.BuildWarning, + description: CreateLocalizableResourceString(nameof(UseVolatileReadDescription)), + isPortedFxCopRule: false, + isDataflowRule: false); + + internal static readonly DiagnosticDescriptor WriteDescriptor = DiagnosticDescriptorHelper.Create( + RuleId, + CreateLocalizableResourceString(nameof(UseVolatileWriteTitle)), + CreateLocalizableResourceString(nameof(UseVolatileWriteMessage)), + DiagnosticCategory.Usage, + RuleLevel.BuildWarning, + description: CreateLocalizableResourceString(nameof(UseVolatileWriteDescription)), + isPortedFxCopRule: false, + isDataflowRule: false); + + public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(ReadDescriptor, WriteDescriptor); + + public override void Initialize(AnalysisContext context) + { + context.EnableConcurrentExecution(); + context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); + context.RegisterCompilationStartAction(context => + { + ImmutableArray threadVolatileReadMethods; + ImmutableArray threadVolatileWriteMethods; + if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingThread, out var threadType) + || (threadVolatileReadMethods = threadType.GetMembers(ThreadVolatileReadMethodName)).IsEmpty + || (threadVolatileWriteMethods = threadType.GetMembers(ThreadVolatileWriteMethodName)).IsEmpty) + { + return; + } + + context.RegisterOperationAction(context => + { + var invocation = (IInvocationOperation)context.Operation; + if (invocation.Instance is not null) + { + return; + } + + if (threadVolatileReadMethods.Contains(invocation.TargetMethod)) + { + context.ReportDiagnostic(invocation.CreateDiagnostic(ReadDescriptor)); + } + else if (threadVolatileWriteMethods.Contains(invocation.TargetMethod)) + { + context.ReportDiagnostic(invocation.CreateDiagnostic(WriteDescriptor)); + } + }, OperationKind.Invocation); + }); + } + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index 6be439919e..63c74ba4ad 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -3223,6 +3223,36 @@ Obecné přetypování (IL unbox.any) používané sekvencí vrácenou metodou E Správně použít hodnot ValueTask + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Zpracování kódu XML z nedůvěryhodných dat může načíst nebezpečné externí odkazy, což by se mělo omezit tím, že se použije XmlReader se zabezpečeným překladačem nebo se zakázaným zpracováním DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index de7796dcd6..606f0f35b5 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -3223,6 +3223,36 @@ Erweiterungen und benutzerdefinierte Konvertierungen werden bei generischen Type ValueTasks ordnungsgemäß verwenden + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Durch das Verarbeiten von XML aus nicht vertrauenswürdigen Daten werden möglicherweise gefährliche externe Verweise geladen, die mithilfe eines XmlReaders mit sicherem Konfliktlöser oder mit deaktivierter DTD-Verarbeitung eingeschränkt werden müssen. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index 0a529da884..9c854c771a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -3223,6 +3223,36 @@ La ampliación y las conversiones definidas por el usuario no se admiten con tip Usar ValueTask correctamente + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Al procesar el código XML desde datos en los que no se confía, se pueden cargar referencias externas peligrosas, que se deben restringir usando un objeto XmlReader con una resolución segura o con el procesamiento de DTD deshabilitado. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index 0e0aac67c8..0e65df4af9 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -3223,6 +3223,36 @@ Les conversions étendues et définies par l’utilisateur ne sont pas prises en Utilisez correctement ValueTasks + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Le traitement XML à partir de données non fiables peut entraîner le chargement de références externes dangereuses. Vous devez limiter ce risque en utilisant un XmlReader avec un programme de résolution sécurisé ou avec une désactivation du traitement DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index 2d2d06ebdc..2cc5feef1d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -3223,6 +3223,36 @@ L'ampliamento e le conversioni definite dall'utente non sono supportate con tipi Usare correttamente gli elementi ValueTask + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Quando si carica codice XML da dati non attendibili, potrebbero essere caricati riferimenti esterni pericolosi, che devono essere limitati usando un elemento XmlReader con un resolver sicuro oppure disabilitando l'elaborazione DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index c334ad1321..3ee29906bd 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -3223,6 +3223,36 @@ Enumerable.OfType<T> で使用されるジェネリック型チェック ( ValueTask を正しく使用する必要があります + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 信頼されていないデータから XML を処理すると、危険な外部参照を読み込む可能性があります。XmlReader を安全なリゾルバーと共に使用するか、DTD 処理を無効にして使用することにより、この処理を制限する必要があります。 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index 08f961f5bf..6aab9ad367 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -3223,6 +3223,36 @@ Enumerable.OfType<T>에서 사용하는 제네릭 형식 검사(C# 'is' 올바르게 ValueTasks 사용 + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 신뢰할 수 없는 데이터의 XML을 처리하면 위험한 외부 참조가 로드될 수 있습니다. 위험한 외부 참조는 안전한 확인자와 함께 또는 DTD 처리를 사용하지 않도록 설정한 상태로 XmlReader를 사용하여 제한해야 합니다. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index a11bd5416e..9af2c8624e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -3223,6 +3223,36 @@ Konwersje poszerzane i zdefiniowane przez użytkownika nie są obsługiwane w pr Użyj elementów ValueTask poprawnie + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Przetwarzanie pliku XML na podstawie niezaufanych danych może spowodować załadowanie niebezpiecznych odwołań zewnętrznych, które powinny zostać ograniczone za pomocą czytnika XmlReader z bezpiecznym programem rozpoznawania nazw lub wyłączonym przetwarzaniem elementów DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index 5d95a9c691..a4aa5678dc 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -3223,6 +3223,36 @@ Ampliação e conversões definidas pelo usuário não são compatíveis com tip Usar ValueTasks corretamente + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. O processamento de XML de dados não confiáveis pode carregar referências externas perigosas, que devem ser restritas usando um XmlReader com um resolvedor seguro ou com o processamento de DTD desabilitado. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index 6efaa02602..b8f257329a 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -3223,6 +3223,36 @@ Widening and user defined conversions are not supported with generic types.Используйте ValueTasks правильно + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Обработка XML-кода из ненадежных данных может привести к загрузке опасных внешних ссылок, что следует ограничить, используя XmlReader с безопасным сопоставителем или отключив обработку DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index ae89dc28a7..3ad1873372 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -3223,6 +3223,36 @@ Genel türlerde genişletme ve kullanıcı tanımlı dönüştürmeler desteklen ValueTask'leri doğru kullanın + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Güvenilmeyen verilerden XML işlenirse tehlikeli dış başvurular yüklenebilir. Bunun, güvenli bir çözümleyicisi olan bir XmlReader kullanılarak veya DTD işleme devre dışı bırakılarak kısıtlanması gerekir. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index 6e2002f85a..01c5c3719e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -3223,6 +3223,36 @@ Enumerable.OfType<T> 使用的泛型类型检查 (C# 'is' operator/IL 'isi 正确使用 ValueTask + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 从不受信任的数据处理 XML 可能会加载危险的外部引用,这应该通过使用带有安全解析程序的 XmlReader 或禁用 DTD 处理来限制。 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index cfc294dbf0..4208956389 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -3223,6 +3223,36 @@ Enumerable.OfType<T> 使用的一般型別檢查 (C# 'is' operator/IL 'isi 正確使用 ValueTasks + + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. + + + + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + Use 'Volatile.Read' instead of 'Thread.VolatileRead' + + + + Use 'Volatile.Read' + Use 'Volatile.Read' + + + + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + + + + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + Use 'Volatile.Write' instead of 'Thread.VolatileWrite' + + + + Use 'Volatile.Write' + Use 'Volatile.Write' + + Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 處理不受信任資料的 XML,可能會載入危險的外部參考,應使用具有安全解析程式或已停用 DTD 處理的 XmlReader,加以限制。 diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index b265ae757f..4ded41046a 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -2586,6 +2586,18 @@ The property 'MaxResponseHeadersLength' is measured in kilobytes, not in bytes. |CodeFix|False| --- +## [CA2263](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2263): Use 'Volatile.Write' + +'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. + +|Item|Value| +|-|-| +|Category|Usage| +|Enabled|True| +|Severity|Warning| +|CodeFix|True| +--- + ## [CA2300](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2300): Do not use insecure deserializer BinaryFormatter The method '{0}' is insecure when deserializing untrusted data. If you need to instead detect BinaryFormatter deserialization without a SerializationBinder set, then disable rule CA2300, and enable rules CA2301 and CA2302. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index e9e8855061..edeeb33dab 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -4474,6 +4474,26 @@ ] } }, + "CA2263": { + "id": "CA2263", + "shortDescription": "Use 'Volatile.Write'", + "fullDescription": "'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead.", + "defaultLevel": "warning", + "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2263", + "properties": { + "category": "Usage", + "isEnabledByDefault": true, + "typeName": "UseVolatileReadWriteAnalyzer", + "languages": [ + "C#", + "Visual Basic" + ], + "tags": [ + "Telemetry", + "EnabledRuleInAggressiveMode" + ] + } + }, "CA2300": { "id": "CA2300", "shortDescription": "Do not use insecure deserializer BinaryFormatter", diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index 118c7c6d88..bc1a1214b0 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -2,18 +2,11 @@ Rule ID | Missing Help Link | Title | --------|-------------------|-------| -CA1510 | | Use ArgumentNullException throw helper | -CA1511 | | Use ArgumentException throw helper | -CA1512 | | Use ArgumentOutOfRangeException throw helper | -CA1513 | | Use ObjectDisposedException throw helper | CA1515 | | Consider making public types internal | -CA1856 | | Incorrect usage of ConstantExpected attribute | -CA1857 | | A constant is expected for the parameter | CA1862 | | Use the 'StringComparison' method overloads to perform case-insensitive string comparisons | CA1863 | | Use 'CompositeFormat' | CA1865 | | Use char overload | CA1866 | | Use char overload | CA1867 | | Use char overload | -CA2021 | | Do not call Enumerable.Cast\ or Enumerable.OfType\ with incompatible types | -CA2261 | | Do not use ConfigureAwaitOptions.SuppressThrowing with Task\ | CA2262 | | Set 'MaxResponseHeadersLength' properly | +CA2263 | | Use 'Volatile.Write' | diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs new file mode 100644 index 0000000000..72dc26728a --- /dev/null +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -0,0 +1,347 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.Testing; +using Xunit; +using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< + Microsoft.NetCore.Analyzers.Usage.UseVolatileReadWriteAnalyzer, + Microsoft.NetCore.CSharp.Analyzers.Usage.CSharpUseVolatileReadWriteFixer>; +using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< + Microsoft.NetCore.Analyzers.Usage.UseVolatileReadWriteAnalyzer, + Microsoft.NetCore.VisualBasic.Analyzers.Usage.BasicUseVolatileReadWriteFixer>; + +namespace Microsoft.NetCore.Analyzers.Usage.UnitTests +{ + public sealed class UseVolatileReadWriteTests + { + [Theory] + [InlineData("IntPtr")] + [InlineData("UIntPtr")] + [InlineData("byte")] + [InlineData("double")] + [InlineData("float")] + [InlineData("int")] + [InlineData("long")] + [InlineData("sbyte")] + [InlineData("short")] + [InlineData("uint")] + [InlineData("ulong")] + [InlineData("ushort")] + public Task CS_UseVolatileRead(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg) + { + {|#0:Thread.VolatileRead(ref arg)|}; + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg) + { + Volatile.Read(ref arg); + } + } + """; + + return new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0) }, + LanguageVersion = LanguageVersion.CSharp8, + ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp30 + }.RunAsync(); + } + + [Fact] + public Task CS_UseVolatileRead_Nullable() + { + const string code = """ + using System; + using System.Threading; + + #nullable enable + class Test + { + void M(object? arg) + { + {|#0:Thread.VolatileRead(ref arg)|}; + } + } + """; + const string fixedCode = """ + using System; + using System.Threading; + + #nullable enable + class Test + { + void M(object? arg) + { + Volatile.Read(ref arg); + } + } + """; + + return new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0) }, + LanguageVersion = LanguageVersion.CSharp8 + }.RunAsync(); + } + + [Fact] + public Task CS_UseVolatileRead_NonNullable() + { + const string code = """ + using System; + using System.Threading; + + class Test + { + void M(object arg) + { + {|#0:Thread.VolatileRead(ref arg)|}; + } + } + """; + const string fixedCode = """ + using System; + using System.Threading; + + class Test + { + void M(object arg) + { + Volatile.Read(ref arg); + } + } + """; + var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0); + + return VerifyCS.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + } + + [Theory] + [InlineData("IntPtr")] + [InlineData("UIntPtr")] + [InlineData("byte")] + [InlineData("double")] + [InlineData("float")] + [InlineData("int")] + [InlineData("long")] + [InlineData("sbyte")] + [InlineData("short")] + [InlineData("uint")] + [InlineData("ulong")] + [InlineData("ushort")] + public Task CS_UseVolatileWrite(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + {|#0:Thread.VolatileWrite(ref arg, value)|}; + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + Volatile.Write(ref arg, value); + } + } + """; + + return new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0) }, + LanguageVersion = LanguageVersion.CSharp8 + }.RunAsync(); + } + + [Fact] + public Task CS_UseVolatileWrite_Nullable() + { + const string code = """ + using System; + using System.Threading; + + #nullable enable + class Test + { + void M(object? arg, object? value) + { + {|#0:Thread.VolatileWrite(ref arg, value)|}; + } + } + """; + const string fixedCode = """ + using System; + using System.Threading; + + #nullable enable + class Test + { + void M(object? arg, object? value) + { + Volatile.Write(ref arg, value); + } + } + """; + + return new VerifyCS.Test + { + TestCode = code, + FixedCode = fixedCode, + ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0) }, + LanguageVersion = LanguageVersion.CSharp8 + }.RunAsync(); + } + + [Fact] + public Task CS_UseVolatileWrite_NonNullable() + { + const string code = """ + using System; + using System.Threading; + + class Test + { + void M(object arg, object value) + { + {|#0:Thread.VolatileWrite(ref arg, value)|}; + } + } + """; + const string fixedCode = """ + using System; + using System.Threading; + + class Test + { + void M(object arg, object value) + { + Volatile.Write(ref arg, value); + } + } + """; + var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0); + + return VerifyCS.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + } + + [Theory] + [InlineData("IntPtr")] + [InlineData("UIntPtr")] + [InlineData("Byte")] + [InlineData("Double")] + [InlineData("Single")] + [InlineData("Integer")] + [InlineData("Long")] + [InlineData("Object")] + [InlineData("Sbyte")] + [InlineData("Short")] + [InlineData("UInteger")] + [InlineData("ULong")] + [InlineData("UShort")] + public Task VB_UseVolatileRead(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}) + {|#0:Thread.VolatileRead(arg)|} + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}) + Volatile.Read(arg) + End Sub + End Class + """; + + var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0); + + return VerifyVB.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + } + + [Theory] + [InlineData("IntPtr")] + [InlineData("UIntPtr")] + [InlineData("Byte")] + [InlineData("Double")] + [InlineData("Single")] + [InlineData("Integer")] + [InlineData("Long")] + [InlineData("Object")] + [InlineData("Sbyte")] + [InlineData("Short")] + [InlineData("UInteger")] + [InlineData("ULong")] + [InlineData("UShort")] + public Task VB_UseVolatileWrite(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}, value As {{type}}) + {|#0:Thread.VolatileWrite(arg, value)|} + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}, value As {type}) + Volatile.Write(arg, value) + End Sub + End Class + """; + + var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0); + + return VerifyVB.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + } + } +} \ No newline at end of file diff --git a/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb new file mode 100644 index 0000000000..567478bc3f --- /dev/null +++ b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb @@ -0,0 +1,27 @@ +Imports System.Composition +Imports System.Runtime.InteropServices +Imports Microsoft.CodeAnalysis +Imports Microsoft.CodeAnalysis.CodeFixes +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax +Imports Microsoft.NetCore.Analyzers.Usage + +Namespace Microsoft.NetCore.VisualBasic.Analyzers.Usage + + + Public NotInheritable Class BasicUseVolatileReadWriteFixer + Inherits UseVolatileReadWriteFixer + Protected Overrides Function TryGetThreadVolatileReadWriteMemberAccess(invocation As SyntaxNode, methodName As String, ByRef memberAccess As SyntaxNode) As Boolean + memberAccess = Nothing + Dim invocationExpression = TryCast(invocation, InvocationExpressionSyntax) + Dim memberAccessExpression = TryCast(invocationExpression.Expression, MemberAccessExpressionSyntax) + If memberAccessExpression IsNot Nothing AndAlso memberAccessExpression.Name.Identifier.Text = methodName + memberAccess = memberAccessExpression + + Return True + End If + + Return False + End Function + End Class + +End Namespace \ No newline at end of file diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt index 18075ef3ad..01aaab0a80 100644 --- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt +++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt @@ -14,7 +14,7 @@ Globalization: CA2101, CA1300-CA1311 Mobility: CA1600-CA1601 Performance: HA, CA1800-CA1870 Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5405 -Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2262 +Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2263 Naming: CA1700-CA1727 Interoperability: CA1400-CA1422 Maintainability: CA1500-CA1515 From fea9ab02ab5c2b2c3f3489915e2fd4ab9e1fcf77 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Thu, 30 Nov 2023 11:52:29 +0100 Subject: [PATCH 02/10] Move analyzer to test project. --- .../Core/AnalyzerReleases.Unshipped.md | 1 - .../Usage/UseVolatileReadWrite.Fixer.cs | 15 +++++++++----- .../Microsoft.CodeAnalysis.NetAnalyzers.md | 12 ----------- .../Microsoft.CodeAnalysis.NetAnalyzers.sarif | 20 ------------------- .../Usage/UseVolatileReadWriteAnalyzer.cs} | 13 ++++++------ .../Usage/UseVolatileReadWriteTests.cs | 4 ++-- .../DiagnosticCategoryAndIdRanges.txt | 2 +- 7 files changed, 19 insertions(+), 48 deletions(-) rename src/NetAnalyzers/{Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs => UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs} (87%) diff --git a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md index a308cb6feb..460ef787ac 100644 --- a/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md +++ b/src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md @@ -7,4 +7,3 @@ Rule ID | Category | Severity | Notes CA1514 | Maintainability | Info | AvoidLengthCheckWhenSlicingToEndAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1514) CA1515 | Maintainability | Disabled | MakeTypesInternal, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca1515) CA2262 | Usage | Info | ProvideHttpClientHandlerMaxResponseHeaderLengthValueCorrectly, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2262) -CA2263 | Usage | Warning | UseVolatileReadWriteAnalyzer, [Documentation](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2263) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs index 9778c70dc1..945ebf3ff8 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs @@ -14,24 +14,29 @@ namespace Microsoft.NetCore.Analyzers.Usage { public abstract class UseVolatileReadWriteFixer : CodeFixProvider { + private const string ThreadVolatileReadMethodName = nameof(Thread.VolatileRead); + private const string ThreadVolatileWriteMethodName = nameof(Thread.VolatileWrite); + private const string VolatileReadMethodName = nameof(Volatile.Read); + private const string VolatileWriteMethodName = nameof(Volatile.Write); + public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); var node = root.FindNode(context.Span, getInnermostNodeForTie: true); - if (TryGetThreadVolatileReadWriteMemberAccess(node, UseVolatileReadWriteAnalyzer.ThreadVolatileReadMethodName, out var readAccess)) + if (TryGetThreadVolatileReadWriteMemberAccess(node, ThreadVolatileReadMethodName, out var readAccess)) { var codeAction = CodeAction.Create( MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle, - _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(readAccess, CreateVolatileMemberAccess(context.Document, UseVolatileReadWriteAnalyzer.VolatileReadMethodName)))), + _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(readAccess, CreateVolatileMemberAccess(context.Document, VolatileReadMethodName)))), MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle ); context.RegisterCodeFix(codeAction, context.Diagnostics); } - else if (TryGetThreadVolatileReadWriteMemberAccess(node, UseVolatileReadWriteAnalyzer.ThreadVolatileWriteMethodName, out var writeAccess)) + else if (TryGetThreadVolatileReadWriteMemberAccess(node, ThreadVolatileWriteMethodName, out var writeAccess)) { var codeAction = CodeAction.Create( MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle, - _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(writeAccess, CreateVolatileMemberAccess(context.Document, UseVolatileReadWriteAnalyzer.VolatileWriteMethodName)))), + _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(writeAccess, CreateVolatileMemberAccess(context.Document, VolatileWriteMethodName)))), MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle ); context.RegisterCodeFix(codeAction, context.Diagnostics); @@ -51,6 +56,6 @@ private static SyntaxNode CreateVolatileMemberAccess(Document document, string m protected abstract bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess); - public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create("CA2263"); + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create("SYSLIB0054"); } } \ No newline at end of file diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md index 4ded41046a..b265ae757f 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.md @@ -2586,18 +2586,6 @@ The property 'MaxResponseHeadersLength' is measured in kilobytes, not in bytes. |CodeFix|False| --- -## [CA2263](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2263): Use 'Volatile.Write' - -'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - -|Item|Value| -|-|-| -|Category|Usage| -|Enabled|True| -|Severity|Warning| -|CodeFix|True| ---- - ## [CA2300](https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2300): Do not use insecure deserializer BinaryFormatter The method '{0}' is insecure when deserializing untrusted data. If you need to instead detect BinaryFormatter deserialization without a SerializationBinder set, then disable rule CA2300, and enable rules CA2301 and CA2302. diff --git a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif index edeeb33dab..e9e8855061 100644 --- a/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif +++ b/src/NetAnalyzers/Microsoft.CodeAnalysis.NetAnalyzers.sarif @@ -4474,26 +4474,6 @@ ] } }, - "CA2263": { - "id": "CA2263", - "shortDescription": "Use 'Volatile.Write'", - "fullDescription": "'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead.", - "defaultLevel": "warning", - "helpUri": "https://learn.microsoft.com/dotnet/fundamentals/code-analysis/quality-rules/ca2263", - "properties": { - "category": "Usage", - "isEnabledByDefault": true, - "typeName": "UseVolatileReadWriteAnalyzer", - "languages": [ - "C#", - "Visual Basic" - ], - "tags": [ - "Telemetry", - "EnabledRuleInAggressiveMode" - ] - } - }, "CA2300": { "id": "CA2300", "shortDescription": "Do not use insecure deserializer BinaryFormatter", diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs similarity index 87% rename from src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs rename to src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs index ae77483a0e..73d82b3e68 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs @@ -8,19 +8,18 @@ using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; -namespace Microsoft.NetCore.Analyzers.Usage +namespace Microsoft.NetCore.Analyzers.Usage.UnitTests { using static MicrosoftNetCoreAnalyzersResources; + // This analyzer can be removed as soon as the Thread.VolatileRead and Thread.VolatileWrite APIs are made obsolete. [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] - public sealed class UseVolatileReadWriteAnalyzer : DiagnosticAnalyzer + internal sealed class UseVolatileReadWriteAnalyzer : DiagnosticAnalyzer { - private const string RuleId = "CA2263"; + private const string RuleId = "SYSLIB0054"; - internal const string ThreadVolatileReadMethodName = nameof(Thread.VolatileRead); - internal const string ThreadVolatileWriteMethodName = nameof(Thread.VolatileWrite); - internal const string VolatileReadMethodName = nameof(Volatile.Read); - internal const string VolatileWriteMethodName = nameof(Volatile.Write); + private const string ThreadVolatileReadMethodName = nameof(Thread.VolatileRead); + private const string ThreadVolatileWriteMethodName = nameof(Thread.VolatileWrite); internal static readonly DiagnosticDescriptor ReadDescriptor = DiagnosticDescriptorHelper.Create( RuleId, diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs index 72dc26728a..c12b51f5db 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -5,10 +5,10 @@ using Microsoft.CodeAnalysis.Testing; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< - Microsoft.NetCore.Analyzers.Usage.UseVolatileReadWriteAnalyzer, + Microsoft.NetCore.Analyzers.Usage.UnitTests.UseVolatileReadWriteAnalyzer, Microsoft.NetCore.CSharp.Analyzers.Usage.CSharpUseVolatileReadWriteFixer>; using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< - Microsoft.NetCore.Analyzers.Usage.UseVolatileReadWriteAnalyzer, + Microsoft.NetCore.Analyzers.Usage.UnitTests.UseVolatileReadWriteAnalyzer, Microsoft.NetCore.VisualBasic.Analyzers.Usage.BasicUseVolatileReadWriteFixer>; namespace Microsoft.NetCore.Analyzers.Usage.UnitTests diff --git a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt index 01aaab0a80..18075ef3ad 100644 --- a/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt +++ b/src/Utilities/Compiler/DiagnosticCategoryAndIdRanges.txt @@ -14,7 +14,7 @@ Globalization: CA2101, CA1300-CA1311 Mobility: CA1600-CA1601 Performance: HA, CA1800-CA1870 Security: CA2100-CA2153, CA2300-CA2330, CA3000-CA3147, CA5300-CA5405 -Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2263 +Usage: CA1801, CA1806, CA1816, CA2200-CA2209, CA2211-CA2262 Naming: CA1700-CA1727 Interoperability: CA1400-CA1422 Maintainability: CA1500-CA1515 From df65c56762c4f27fb9e19163d295e52a158f3b24 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Thu, 30 Nov 2023 11:55:01 +0100 Subject: [PATCH 03/10] Update RulesMissingDocumentation.md --- src/NetAnalyzers/RulesMissingDocumentation.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/NetAnalyzers/RulesMissingDocumentation.md b/src/NetAnalyzers/RulesMissingDocumentation.md index bc1a1214b0..0c3d9d554b 100644 --- a/src/NetAnalyzers/RulesMissingDocumentation.md +++ b/src/NetAnalyzers/RulesMissingDocumentation.md @@ -3,10 +3,4 @@ Rule ID | Missing Help Link | Title | --------|-------------------|-------| CA1515 | | Consider making public types internal | -CA1862 | | Use the 'StringComparison' method overloads to perform case-insensitive string comparisons | -CA1863 | | Use 'CompositeFormat' | -CA1865 | | Use char overload | -CA1866 | | Use char overload | -CA1867 | | Use char overload | CA2262 | | Set 'MaxResponseHeadersLength' properly | -CA2263 | | Use 'Volatile.Write' | From 6fe41cb4f6cf29bfbfc1b53ccc323ec3854bbea3 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Tue, 5 Dec 2023 18:56:32 +0100 Subject: [PATCH 04/10] Add copyright comment --- .../Usage/BasicUseVolatileReadWriteFixer.vb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb index 567478bc3f..707c891e84 100644 --- a/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb +++ b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb @@ -1,3 +1,5 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. + Imports System.Composition Imports System.Runtime.InteropServices Imports Microsoft.CodeAnalysis From 3be32e086cc9b4c12c4c1ce9acff01d111f4623d Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Wed, 6 Mar 2024 22:06:24 +0100 Subject: [PATCH 05/10] Remove analyzer from test project --- .../MicrosoftNetCoreAnalyzersResources.resx | 19 +- .../Usage/UseVolatileReadWrite.Fixer.cs | 8 +- .../MicrosoftNetCoreAnalyzersResources.cs.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.de.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.es.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.fr.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.it.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.ja.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.ko.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.pl.xlf | 35 +-- ...crosoftNetCoreAnalyzersResources.pt-BR.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.ru.xlf | 35 +-- .../MicrosoftNetCoreAnalyzersResources.tr.xlf | 35 +-- ...osoftNetCoreAnalyzersResources.zh-Hans.xlf | 35 +-- ...osoftNetCoreAnalyzersResources.zh-Hant.xlf | 35 +-- .../Usage/UseVolatileReadWriteAnalyzer.cs | 81 ----- .../Usage/UseVolatileReadWriteTests.cs | 286 +++++++++++++++--- 17 files changed, 317 insertions(+), 532 deletions(-) delete mode 100644 src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx index 142e664b8d..77e89fc98e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/MicrosoftNetCoreAnalyzersResources.resx @@ -2132,22 +2132,7 @@ Widening and user defined conversions are not supported with generic types. Replace the 'ArgumentNullException.ThrowIfNull' call with a conditional - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - Use 'Volatile.Read' - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - Use 'Volatile.Write' + + Replace obsolete call diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs index 945ebf3ff8..1957a4fe2d 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs @@ -26,18 +26,18 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) if (TryGetThreadVolatileReadWriteMemberAccess(node, ThreadVolatileReadMethodName, out var readAccess)) { var codeAction = CodeAction.Create( - MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle, + MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle, _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(readAccess, CreateVolatileMemberAccess(context.Document, VolatileReadMethodName)))), - MicrosoftNetCoreAnalyzersResources.UseVolatileReadTitle + nameof(MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle) ); context.RegisterCodeFix(codeAction, context.Diagnostics); } else if (TryGetThreadVolatileReadWriteMemberAccess(node, ThreadVolatileWriteMethodName, out var writeAccess)) { var codeAction = CodeAction.Create( - MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle, + MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle, _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(writeAccess, CreateVolatileMemberAccess(context.Document, VolatileWriteMethodName)))), - MicrosoftNetCoreAnalyzersResources.UseVolatileWriteTitle + nameof(MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle) ); context.RegisterCodeFix(codeAction, context.Diagnostics); } diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf index b641b8b424..c1f4b8e4ce 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.cs.xlf @@ -1138,6 +1138,11 @@ Obecné přetypování (IL unbox.any) používané sekvencí vrácenou metodou E Nepoužívat stackalloc ve smyčkách + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Častější pravidelná aktivita bude zatěžovat procesor a ovlivňovat časovače neaktivity, které šetří energii a vypínají displej a pevné disky. @@ -3283,36 +3288,6 @@ Obecné přetypování (IL unbox.any) používané sekvencí vrácenou metodou E Správně použít hodnot ValueTask - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Zpracování kódu XML z nedůvěryhodných dat může načíst nebezpečné externí odkazy, což by se mělo omezit tím, že se použije XmlReader se zabezpečeným překladačem nebo se zakázaným zpracováním DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf index 212c2a8813..913d3e14c0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.de.xlf @@ -1138,6 +1138,11 @@ Erweiterungen und benutzerdefinierte Konvertierungen werden bei generischen Type stackalloc nicht in Schleifen verwenden + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Regelmäßige Aktivitäten mit einer höheren Frequenz belasten die CPU und beeinflussen energiesparende Leerlauftimer, mit denen die Anzeige sowie die Festplatten ausgeschaltet werden. @@ -3283,36 +3288,6 @@ Erweiterungen und benutzerdefinierte Konvertierungen werden bei generischen Type ValueTasks ordnungsgemäß verwenden - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Durch das Verarbeiten von XML aus nicht vertrauenswürdigen Daten werden möglicherweise gefährliche externe Verweise geladen, die mithilfe eines XmlReaders mit sicherem Konfliktlöser oder mit deaktivierter DTD-Verarbeitung eingeschränkt werden müssen. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf index 268187770c..58551e83ce 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.es.xlf @@ -1138,6 +1138,11 @@ La ampliación y las conversiones definidas por el usuario no se admiten con tip No utilizar stackalloc en los bucles + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Una actividad periódica más frecuente ocupará la CPU e interferirá con los temporizadores de inactividad para ahorro de energía que apagan el monitor y los discos duros. @@ -3283,36 +3288,6 @@ La ampliación y las conversiones definidas por el usuario no se admiten con tip Usar ValueTask correctamente - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Al procesar el código XML desde datos en los que no se confía, se pueden cargar referencias externas peligrosas, que se deben restringir usando un objeto XmlReader con una resolución segura o con el procesamiento de DTD deshabilitado. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf index a5d5946d2f..8f6c619b78 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.fr.xlf @@ -1138,6 +1138,11 @@ Les conversions étendues et définies par l’utilisateur ne sont pas prises en N'utilisez pas stackalloc dans les boucles + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Une activité régulière à plus grande fréquence occupe le processeur et interfère avec les minuteurs d'inactivité qui déclenchent la mise en veille de l'écran et des disques durs pour économiser de l'énergie. @@ -3283,36 +3288,6 @@ Les conversions étendues et définies par l’utilisateur ne sont pas prises en Utilisez correctement ValueTasks - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Le traitement XML à partir de données non fiables peut entraîner le chargement de références externes dangereuses. Vous devez limiter ce risque en utilisant un XmlReader avec un programme de résolution sécurisé ou avec une désactivation du traitement DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf index bd156320fe..17fd704187 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.it.xlf @@ -1138,6 +1138,11 @@ L'ampliamento e le conversioni definite dall'utente non sono supportate con tipi Non usare stackalloc nei cicli + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Un'attività periodica più frequente tiene la CPU occupata e interferisce con i timer di inattività per il risparmio di energia che disattivano lo schermo e i dischi rigidi. @@ -3283,36 +3288,6 @@ L'ampliamento e le conversioni definite dall'utente non sono supportate con tipi Usare correttamente gli elementi ValueTask - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Quando si carica codice XML da dati non attendibili, potrebbero essere caricati riferimenti esterni pericolosi, che devono essere limitati usando un elemento XmlReader con un resolver sicuro oppure disabilitando l'elaborazione DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf index b4cea50e1f..1167c1e00b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ja.xlf @@ -1138,6 +1138,11 @@ Enumerable.OfType<T> で使用されるジェネリック型チェック ( stackalloc はループ内で使用不可 + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. 頻度の高い定期的な動作は CPU のビジー状態を維持し、画面およびハード ディスクの電源を切る節電アイドル タイマーに影響します。 @@ -3283,36 +3288,6 @@ Enumerable.OfType<T> で使用されるジェネリック型チェック ( ValueTask を正しく使用する必要があります - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 信頼されていないデータから XML を処理すると、危険な外部参照を読み込む可能性があります。XmlReader を安全なリゾルバーと共に使用するか、DTD 処理を無効にして使用することにより、この処理を制限する必要があります。 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf index b8979ac034..5fb255ed6f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ko.xlf @@ -1138,6 +1138,11 @@ Enumerable.OfType<T>에서 사용하는 제네릭 형식 검사(C# 'is' 루프에서 stackalloc을 사용하면 안 됨 + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. 정기적인 작업의 실행 빈도가 높아지면 CPU 사용률도 높아져 디스플레이 및 하드 디스크를 끄는 절전 유휴 타이머에 방해가 됩니다. @@ -3283,36 +3288,6 @@ Enumerable.OfType<T>에서 사용하는 제네릭 형식 검사(C# 'is' 올바르게 ValueTasks 사용 - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 신뢰할 수 없는 데이터의 XML을 처리하면 위험한 외부 참조가 로드될 수 있습니다. 위험한 외부 참조는 안전한 확인자와 함께 또는 DTD 처리를 사용하지 않도록 설정한 상태로 XmlReader를 사용하여 제한해야 합니다. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf index 88ffc76e50..d87b39c91b 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pl.xlf @@ -1138,6 +1138,11 @@ Konwersje poszerzane i zdefiniowane przez użytkownika nie są obsługiwane w pr Nie używaj słowa kluczowego stackalloc w pętlach + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Działania okresowe wykonywane z dużą częstotliwością utrzymują zajętość procesora CPU i wpływają na czasomierze bezczynności funkcji oszczędzania energii, które powodują wyłączanie ekranu i dysków twardych. @@ -3283,36 +3288,6 @@ Konwersje poszerzane i zdefiniowane przez użytkownika nie są obsługiwane w pr Użyj elementów ValueTask poprawnie - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Przetwarzanie pliku XML na podstawie niezaufanych danych może spowodować załadowanie niebezpiecznych odwołań zewnętrznych, które powinny zostać ograniczone za pomocą czytnika XmlReader z bezpiecznym programem rozpoznawania nazw lub wyłączonym przetwarzaniem elementów DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf index dbad932d58..b24e49736f 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.pt-BR.xlf @@ -1138,6 +1138,11 @@ Ampliação e conversões definidas pelo usuário não são compatíveis com tip Não use stackalloc em loops + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Atividade periódica de alta frequência manterá a CPU ocupada e interferirá nos medidores de tempo ocioso para economia de energia que desligam o visor e os discos rígidos. @@ -3283,36 +3288,6 @@ Ampliação e conversões definidas pelo usuário não são compatíveis com tip Usar ValueTasks corretamente - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. O processamento de XML de dados não confiáveis pode carregar referências externas perigosas, que devem ser restritas usando um XmlReader com um resolvedor seguro ou com o processamento de DTD desabilitado. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf index 6899c0f97e..c31e122398 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.ru.xlf @@ -1138,6 +1138,11 @@ Widening and user defined conversions are not supported with generic types.Запрет использования stackalloc в циклах + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Периодическая активность с более высокой частотой заставит ЦП переключаться в активный режим и помешает работе энергосберегающих таймеров простоя, которые отключают дисплей и жесткие диски. @@ -3283,36 +3288,6 @@ Widening and user defined conversions are not supported with generic types.Используйте ValueTasks правильно - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Обработка XML-кода из ненадежных данных может привести к загрузке опасных внешних ссылок, что следует ограничить, используя XmlReader с безопасным сопоставителем или отключив обработку DTD. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf index d6e31abeae..ed5000c9b0 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.tr.xlf @@ -1138,6 +1138,11 @@ Genel türlerde genişletme ve kullanıcı tanımlı dönüştürmeler desteklen Döngüler içinde stackalloc kullanmayın + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. Daha yüksek frekanslı düzenli etkinlik, CPU’nun meşgul kalmasına neden olmasının yanı sıra ekranı ve sabit diskleri kapatarak güç tasarrufu sağlayan boşta süreölçerlerini etkileyebilir. @@ -3283,36 +3288,6 @@ Genel türlerde genişletme ve kullanıcı tanımlı dönüştürmeler desteklen ValueTask'leri doğru kullanın - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. Güvenilmeyen verilerden XML işlenirse tehlikeli dış başvurular yüklenebilir. Bunun, güvenli bir çözümleyicisi olan bir XmlReader kullanılarak veya DTD işleme devre dışı bırakılarak kısıtlanması gerekir. diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf index 3972d32b7d..0ced3f68d5 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hans.xlf @@ -1138,6 +1138,11 @@ Enumerable.OfType<T> 使用的泛型类型检查 (C# 'is' operator/IL 'isi 不要循环使用 stackalloc + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. 频率较高的定期活动会使 CPU 处于忙状态并且干扰具有节能功能(关闭显示器和硬盘)的空闲计时器。 @@ -3283,36 +3288,6 @@ Enumerable.OfType<T> 使用的泛型类型检查 (C# 'is' operator/IL 'isi 正确使用 ValueTask - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 从不受信任的数据处理 XML 可能会加载危险的外部引用,这应该通过使用带有安全解析程序的 XmlReader 或禁用 DTD 处理来限制。 diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf index e9763fd86a..9d69b639fe 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/xlf/MicrosoftNetCoreAnalyzersResources.zh-Hant.xlf @@ -1138,6 +1138,11 @@ Enumerable.OfType<T> 使用的一般型別檢查 (C# 'is' operator/IL 'isi 請勿在迴圈中使用 stackalloc + + Replace obsolete call + Replace obsolete call + + Higher-frequency periodic activity will keep the CPU busy and interfere with power-saving idle timers that turn off the display and hard disks. 更高頻率的週期性活動,會讓 CPU 一直處於忙碌狀態,且會干擾關閉顯示器與硬碟的省電閒置計時器。 @@ -3283,36 +3288,6 @@ Enumerable.OfType<T> 使用的一般型別檢查 (C# 'is' operator/IL 'isi 正確使用 ValueTasks - - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - 'Thread.VolatileRead' is considered obsolete. Use 'Volatile.Read' instead. - - - - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - Use 'Volatile.Read' instead of 'Thread.VolatileRead' - - - - Use 'Volatile.Read' - Use 'Volatile.Read' - - - - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - 'Thread.VolatileWrite' is considered obsolete. Use 'Volatile.Write' instead. - - - - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - Use 'Volatile.Write' instead of 'Thread.VolatileWrite' - - - - Use 'Volatile.Write' - Use 'Volatile.Write' - - Processing XML from untrusted data may load dangerous external references, which should be restricted by using an XmlReader with a secure resolver or with DTD processing disabled. 處理不受信任資料的 XML,可能會載入危險的外部參考,應使用具有安全解析程式或已停用 DTD 處理的 XmlReader,加以限制。 diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs deleted file mode 100644 index 73d82b3e68..0000000000 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteAnalyzer.cs +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. - -using System.Collections.Immutable; -using System.Threading; -using Analyzer.Utilities; -using Analyzer.Utilities.Extensions; -using Microsoft.CodeAnalysis; -using Microsoft.CodeAnalysis.Diagnostics; -using Microsoft.CodeAnalysis.Operations; - -namespace Microsoft.NetCore.Analyzers.Usage.UnitTests -{ - using static MicrosoftNetCoreAnalyzersResources; - - // This analyzer can be removed as soon as the Thread.VolatileRead and Thread.VolatileWrite APIs are made obsolete. - [DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)] - internal sealed class UseVolatileReadWriteAnalyzer : DiagnosticAnalyzer - { - private const string RuleId = "SYSLIB0054"; - - private const string ThreadVolatileReadMethodName = nameof(Thread.VolatileRead); - private const string ThreadVolatileWriteMethodName = nameof(Thread.VolatileWrite); - - internal static readonly DiagnosticDescriptor ReadDescriptor = DiagnosticDescriptorHelper.Create( - RuleId, - CreateLocalizableResourceString(nameof(UseVolatileReadTitle)), - CreateLocalizableResourceString(nameof(UseVolatileReadMessage)), - DiagnosticCategory.Usage, - RuleLevel.BuildWarning, - description: CreateLocalizableResourceString(nameof(UseVolatileReadDescription)), - isPortedFxCopRule: false, - isDataflowRule: false); - - internal static readonly DiagnosticDescriptor WriteDescriptor = DiagnosticDescriptorHelper.Create( - RuleId, - CreateLocalizableResourceString(nameof(UseVolatileWriteTitle)), - CreateLocalizableResourceString(nameof(UseVolatileWriteMessage)), - DiagnosticCategory.Usage, - RuleLevel.BuildWarning, - description: CreateLocalizableResourceString(nameof(UseVolatileWriteDescription)), - isPortedFxCopRule: false, - isDataflowRule: false); - - public override ImmutableArray SupportedDiagnostics { get; } = ImmutableArray.Create(ReadDescriptor, WriteDescriptor); - - public override void Initialize(AnalysisContext context) - { - context.EnableConcurrentExecution(); - context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); - context.RegisterCompilationStartAction(context => - { - ImmutableArray threadVolatileReadMethods; - ImmutableArray threadVolatileWriteMethods; - if (!context.Compilation.TryGetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingThread, out var threadType) - || (threadVolatileReadMethods = threadType.GetMembers(ThreadVolatileReadMethodName)).IsEmpty - || (threadVolatileWriteMethods = threadType.GetMembers(ThreadVolatileWriteMethodName)).IsEmpty) - { - return; - } - - context.RegisterOperationAction(context => - { - var invocation = (IInvocationOperation)context.Operation; - if (invocation.Instance is not null) - { - return; - } - - if (threadVolatileReadMethods.Contains(invocation.TargetMethod)) - { - context.ReportDiagnostic(invocation.CreateDiagnostic(ReadDescriptor)); - } - else if (threadVolatileWriteMethods.Contains(invocation.TargetMethod)) - { - context.ReportDiagnostic(invocation.CreateDiagnostic(WriteDescriptor)); - } - }, OperationKind.Invocation); - }); - } - } -} \ No newline at end of file diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs index c12b51f5db..a00841f8ef 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -1,20 +1,222 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. using System.Threading.Tasks; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Testing; using Xunit; using VerifyCS = Test.Utilities.CSharpCodeFixVerifier< - Microsoft.NetCore.Analyzers.Usage.UnitTests.UseVolatileReadWriteAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer, Microsoft.NetCore.CSharp.Analyzers.Usage.CSharpUseVolatileReadWriteFixer>; using VerifyVB = Test.Utilities.VisualBasicCodeFixVerifier< - Microsoft.NetCore.Analyzers.Usage.UnitTests.UseVolatileReadWriteAnalyzer, + Microsoft.CodeAnalysis.Testing.EmptyDiagnosticAnalyzer, Microsoft.NetCore.VisualBasic.Analyzers.Usage.BasicUseVolatileReadWriteFixer>; namespace Microsoft.NetCore.Analyzers.Usage.UnitTests { public sealed class UseVolatileReadWriteTests { + private const string CsharpSystemThreadingThread = """ + namespace System.Threading + { + public sealed class Thread + { + private const string ObsoletionDiagnosticId = "SYSLIB0054"; + + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static byte VolatileRead(ref byte address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static double VolatileRead(ref double address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static short VolatileRead(ref short address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static int VolatileRead(ref int address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static long VolatileRead(ref long address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static IntPtr VolatileRead(ref IntPtr address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static object VolatileRead(ref object address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static sbyte VolatileRead(ref sbyte address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static float VolatileRead(ref float address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static ushort VolatileRead(ref ushort address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static uint VolatileRead(ref uint address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static ulong VolatileRead(ref ulong address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static UIntPtr VolatileRead(ref UIntPtr address) => Volatile.Read(ref address); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref byte address, byte value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref double address, double value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref short address, short value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref int address, int value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref long address, long value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref IntPtr address, IntPtr value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref object address, object value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref sbyte address, sbyte value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref float address, float value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref ushort address, ushort value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref uint address, uint value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref ulong address, ulong value) => Volatile.Write(ref address, value); + [Obsolete(DiagnosticId = ObsoletionDiagnosticId)] + public static void VolatileWrite(ref UIntPtr address, UIntPtr value) => Volatile.Write(ref address, value); + } + } + """; + + private const string VisualBasicSystemThreadingThread = """ + Namespace System.Threading + Public NotInheritable Class Thread + Private Const ObsoletionDiagnosticId = "SYSLIB0054" + + + Public Shared Function VolatileRead(ByRef address As Byte) As Byte + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As Double) As Double + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As Short) As Short + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As Int32) As Int32 + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As Int64) As Int64 + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As IntPtr) As IntPtr + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As Object) As Object + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As SByte) As SByte + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As Single) As Single + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As UInt16) As UInt16 + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As UInt32) As UInt32 + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As UInt64) As UInt64 + Volatile.Read(address) + End Function + + + Public Shared Function VolatileRead(ByRef address As UIntPtr) As UIntPtr + Volatile.Read(address) + End Function + + + Public Shared Sub VolatileWrite(ByRef address As Byte, value As Byte) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As Double, value As Double) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As Int16, value As Int16) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As Int32, value As Int32) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As Int64, value As Int64) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As IntPtr, value As IntPtr) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As Object, value As Object) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As SByte, value As SByte) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As Single, value As Single) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As UInt16, value As UInt16) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As UInt32, value As UInt32) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As Uint64, value As Uint64) + Volatile.Write(address, value) + End Sub + + + Public Shared Sub VolatileWrite(ByRef address As UIntPtr, value As UIntPtr) + Volatile.Write(address, value) + End Sub + End Class + End Namespace + """; + [Theory] [InlineData("IntPtr")] [InlineData("UIntPtr")] @@ -57,14 +259,7 @@ void M({{type}} arg) } """; - return new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0) }, - LanguageVersion = LanguageVersion.CSharp8, - ReferenceAssemblies = ReferenceAssemblies.NetCore.NetCoreApp30 - }.RunAsync(); + return VerifyCsharpAsync(code, fixedCode); } [Fact] @@ -97,13 +292,7 @@ void M(object? arg) } """; - return new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0) }, - LanguageVersion = LanguageVersion.CSharp8 - }.RunAsync(); + return VerifyCsharpAsync(code, fixedCode); } [Fact] @@ -133,9 +322,8 @@ void M(object arg) } } """; - var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0); - return VerifyCS.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + return VerifyCsharpAsync(code, fixedCode); } [Theory] @@ -180,13 +368,7 @@ void M({{type}} arg, {{type}} value) } """; - return new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0) }, - LanguageVersion = LanguageVersion.CSharp8 - }.RunAsync(); + return VerifyCsharpAsync(code, fixedCode); } [Fact] @@ -219,13 +401,7 @@ void M(object? arg, object? value) } """; - return new VerifyCS.Test - { - TestCode = code, - FixedCode = fixedCode, - ExpectedDiagnostics = { new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0) }, - LanguageVersion = LanguageVersion.CSharp8 - }.RunAsync(); + return VerifyCsharpAsync(code, fixedCode); } [Fact] @@ -255,9 +431,8 @@ void M(object arg, object value) } } """; - var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0); - return VerifyCS.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + return VerifyCsharpAsync(code, fixedCode); } [Theory] @@ -297,9 +472,7 @@ End Sub End Class """; - var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.ReadDescriptor).WithLocation(0); - - return VerifyVB.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + return VerifyVisualBasicAsync(code, fixedCode); } [Theory] @@ -339,9 +512,42 @@ End Sub End Class """; - var expectedDiagnostic = new DiagnosticResult(UseVolatileReadWriteAnalyzer.WriteDescriptor).WithLocation(0); + return VerifyVisualBasicAsync(code, fixedCode); + } - return VerifyVB.VerifyCodeFixAsync(code, expectedDiagnostic, fixedCode); + private static Task VerifyCsharpAsync(string code, string fixedCode) + { + return new VerifyCS.Test + { + TestState = + { + Sources = { code, CsharpSystemThreadingThread } + }, + FixedState = + { + Sources = { fixedCode, CsharpSystemThreadingThread } + }, + ExpectedDiagnostics = { new DiagnosticResult("SYSLIB0054", DiagnosticSeverity.Warning).WithLocation(0) }, + LanguageVersion = LanguageVersion.CSharp8, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50 + }.RunAsync(); + } + + private static Task VerifyVisualBasicAsync(string code, string fixedCode) + { + return new VerifyVB.Test + { + TestState = + { + Sources = { code, VisualBasicSystemThreadingThread } + }, + FixedState = + { + Sources = { fixedCode, VisualBasicSystemThreadingThread } + }, + ExpectedDiagnostics = { new DiagnosticResult("SYSLIB0054", DiagnosticSeverity.Warning).WithLocation(0) }, + ReferenceAssemblies = ReferenceAssemblies.Net.Net50 + }.RunAsync(); } } } \ No newline at end of file From 335a3e8b5550718016b26b8e467b0caa3150dd6c Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Wed, 6 Mar 2024 23:07:44 +0100 Subject: [PATCH 06/10] Add tests for named arguments and trivia --- .../Usage/CSharpUseVolatileReadWriteFixer.cs | 10 +- .../Usage/UseVolatileReadWrite.Fixer.cs | 21 +- .../Usage/UseVolatileReadWriteTests.cs | 386 ++++++++++++++---- .../Usage/BasicUseVolatileReadWriteFixer.vb | 6 +- 4 files changed, 330 insertions(+), 93 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs index 09da3e89d9..55399ba0f3 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs @@ -1,7 +1,9 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. +using System.Collections.Generic; using System.Composition; using System.Diagnostics.CodeAnalysis; +using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -12,12 +14,12 @@ namespace Microsoft.NetCore.CSharp.Analyzers.Usage [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal sealed class CSharpUseVolatileReadWriteFixer : UseVolatileReadWriteFixer { - protected override bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess) + protected override bool TryGetThreadVolatileReadWriteArguments(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out IEnumerable? arguments) { - memberAccess = null; - if (invocation is InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax m } && m.Name.Identifier.Text == methodName) + arguments = null; + if (invocation is InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax m } i && m.Name.Identifier.Text == methodName) { - memberAccess = m; + arguments = i.ArgumentList.Arguments.Select(a => a.WithNameColon(null)); return true; } diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs index 1957a4fe2d..00bb42980e 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs @@ -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.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics.CodeAnalysis; using System.Threading; @@ -23,39 +24,41 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); var node = root.FindNode(context.Span, getInnermostNodeForTie: true); - if (TryGetThreadVolatileReadWriteMemberAccess(node, ThreadVolatileReadMethodName, out var readAccess)) + if (TryGetThreadVolatileReadWriteArguments(node, ThreadVolatileReadMethodName, out var arguments)) { var codeAction = CodeAction.Create( MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle, - _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(readAccess, CreateVolatileMemberAccess(context.Document, VolatileReadMethodName)))), + _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(node, CreateVolatileMemberAccess(context.Document, VolatileReadMethodName, arguments).WithTriviaFrom(node)))), nameof(MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle) ); context.RegisterCodeFix(codeAction, context.Diagnostics); } - else if (TryGetThreadVolatileReadWriteMemberAccess(node, ThreadVolatileWriteMethodName, out var writeAccess)) + else if (TryGetThreadVolatileReadWriteArguments(node, ThreadVolatileWriteMethodName, out arguments)) { var codeAction = CodeAction.Create( MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle, - _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(writeAccess, CreateVolatileMemberAccess(context.Document, VolatileWriteMethodName)))), + _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(node, CreateVolatileMemberAccess(context.Document, VolatileWriteMethodName, arguments).WithTriviaFrom(node)))), nameof(MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle) ); context.RegisterCodeFix(codeAction, context.Diagnostics); } } - private static SyntaxNode CreateVolatileMemberAccess(Document document, string methodName) + private static SyntaxNode CreateVolatileMemberAccess(Document document, string methodName, IEnumerable arguments) { var generator = SyntaxGenerator.GetGenerator(document); - return generator.MemberAccessExpression( + var memberAccess = generator.MemberAccessExpression( generator.IdentifierName(nameof(Volatile)), generator.IdentifierName(methodName) ); + + return generator.InvocationExpression(memberAccess, arguments); } - public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; - protected abstract bool TryGetThreadVolatileReadWriteMemberAccess(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out SyntaxNode? memberAccess); + protected abstract bool TryGetThreadVolatileReadWriteArguments(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out IEnumerable? arguments); - public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create("SYSLIB0054"); + public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create("SYSLIB0054"); } } \ No newline at end of file diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs index a00841f8ef..e27bc2e942 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -88,127 +88,102 @@ Public NotInheritable Class Thread Public Shared Function VolatileRead(ByRef address As Byte) As Byte Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As Double) As Double Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As Short) As Short Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As Int32) As Int32 Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As Int64) As Int64 Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As IntPtr) As IntPtr Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As Object) As Object Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As SByte) As SByte Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As Single) As Single Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As UInt16) As UInt16 Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As UInt32) As UInt32 Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As UInt64) As UInt64 Volatile.Read(address) End Function - Public Shared Function VolatileRead(ByRef address As UIntPtr) As UIntPtr Volatile.Read(address) End Function - Public Shared Sub VolatileWrite(ByRef address As Byte, value As Byte) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As Double, value As Double) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As Int16, value As Int16) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As Int32, value As Int32) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As Int64, value As Int64) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As IntPtr, value As IntPtr) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As Object, value As Object) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As SByte, value As SByte) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As Single, value As Single) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As UInt16, value As UInt16) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As UInt32, value As UInt32) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As Uint64, value As Uint64) Volatile.Write(address, value) End Sub - Public Shared Sub VolatileWrite(ByRef address As UIntPtr, value As UIntPtr) Volatile.Write(address, value) @@ -217,19 +192,41 @@ End Class End Namespace """; + public static readonly TheoryData CSharpTypes = new() + { + "IntPtr", + "UIntPtr", + "byte", + "double", + "float", + "int", + "long", + "sbyte", + "short", + "uint", + "ulong", + "ushort" + }; + + public static readonly TheoryData VisualBasicTypes = new() + { + "IntPtr", + "UIntPtr", + "Byte", + "Double", + "Single", + "Integer", + "Long", + "Object", + "Sbyte", + "Short", + "UInteger", + "ULong", + "UShort" + }; + [Theory] - [InlineData("IntPtr")] - [InlineData("UIntPtr")] - [InlineData("byte")] - [InlineData("double")] - [InlineData("float")] - [InlineData("int")] - [InlineData("long")] - [InlineData("sbyte")] - [InlineData("short")] - [InlineData("uint")] - [InlineData("ulong")] - [InlineData("ushort")] + [MemberData(nameof(CSharpTypes))] public Task CS_UseVolatileRead(string type) { var code = $$""" @@ -262,6 +259,78 @@ void M({{type}} arg) return VerifyCsharpAsync(code, fixedCode); } + [Theory] + [MemberData(nameof(CSharpTypes))] + public Task CS_UseVolatileRead_WithNamedArguments(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg) + { + {|#0:Thread.VolatileRead(address: ref arg)|}; + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg) + { + Volatile.Read(ref arg); + } + } + """; + + return VerifyCsharpAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(CSharpTypes))] + public Task CS_UseVolatileRead_WithTrivia(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg) + { + // Trivia prefix + {|#0:Thread.VolatileRead(ref arg)|}; // Trivia infix + // Trivia suffix + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg) + { + // Trivia prefix + Volatile.Read(ref arg); // Trivia infix + // Trivia suffix + } + } + """; + + return VerifyCsharpAsync(code, fixedCode); + } + [Fact] public Task CS_UseVolatileRead_Nullable() { @@ -327,18 +396,7 @@ void M(object arg) } [Theory] - [InlineData("IntPtr")] - [InlineData("UIntPtr")] - [InlineData("byte")] - [InlineData("double")] - [InlineData("float")] - [InlineData("int")] - [InlineData("long")] - [InlineData("sbyte")] - [InlineData("short")] - [InlineData("uint")] - [InlineData("ulong")] - [InlineData("ushort")] + [MemberData(nameof(CSharpTypes))] public Task CS_UseVolatileWrite(string type) { var code = $$""" @@ -371,6 +429,78 @@ void M({{type}} arg, {{type}} value) return VerifyCsharpAsync(code, fixedCode); } + [Theory] + [MemberData(nameof(CSharpTypes))] + public Task CS_UseVolatileWrite_WithNamedArguments(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + {|#0:Thread.VolatileWrite(address: ref arg, value: value)|}; + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + Volatile.Write(ref arg, value); + } + } + """; + + return VerifyCsharpAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(CSharpTypes))] + public Task CS_UseVolatileWrite_WithWrivia(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + // Trivia prefix + {|#0:Thread.VolatileWrite(ref arg, value)|}; // Trivia infix + // Trivia suffix + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + // Trivia prefix + Volatile.Write(ref arg, value); // Trivia infix + // Trivia suffix + } + } + """; + + return VerifyCsharpAsync(code, fixedCode); + } + [Fact] public Task CS_UseVolatileWrite_Nullable() { @@ -436,19 +566,7 @@ void M(object arg, object value) } [Theory] - [InlineData("IntPtr")] - [InlineData("UIntPtr")] - [InlineData("Byte")] - [InlineData("Double")] - [InlineData("Single")] - [InlineData("Integer")] - [InlineData("Long")] - [InlineData("Object")] - [InlineData("Sbyte")] - [InlineData("Short")] - [InlineData("UInteger")] - [InlineData("ULong")] - [InlineData("UShort")] + [MemberData(nameof(VisualBasicTypes))] public Task VB_UseVolatileRead(string type) { var code = $$""" @@ -476,19 +594,67 @@ End Class } [Theory] - [InlineData("IntPtr")] - [InlineData("UIntPtr")] - [InlineData("Byte")] - [InlineData("Double")] - [InlineData("Single")] - [InlineData("Integer")] - [InlineData("Long")] - [InlineData("Object")] - [InlineData("Sbyte")] - [InlineData("Short")] - [InlineData("UInteger")] - [InlineData("ULong")] - [InlineData("UShort")] + [MemberData(nameof(VisualBasicTypes))] + public Task VB_UseVolatileRead_WithNamedArguments(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}) + {|#0:Thread.VolatileRead(address:=arg)|} + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}) + Volatile.Read(arg) + End Sub + End Class + """; + + return VerifyVisualBasicAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(VisualBasicTypes))] + public Task VB_UseVolatileRead_WithTrivia(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}) + ' Trivia prefix + {|#0:Thread.VolatileRead(arg)|} ' Trivia infix + ' Trivia suffix + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}) + ' Trivia prefix + Volatile.Read(arg) ' Trivia infix + ' Trivia suffix + End Sub + End Class + """; + + return VerifyVisualBasicAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(VisualBasicTypes))] public Task VB_UseVolatileWrite(string type) { var code = $$""" @@ -515,6 +681,66 @@ End Class return VerifyVisualBasicAsync(code, fixedCode); } + [Theory] + [MemberData(nameof(VisualBasicTypes))] + public Task VB_UseVolatileWrite_WithNamedArguments(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}, value As {{type}}) + {|#0:Thread.VolatileWrite(address:=arg, value:=value)|} + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}, value As {type}) + Volatile.Write(arg, value) + End Sub + End Class + """; + + return VerifyVisualBasicAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(VisualBasicTypes))] + public Task VB_UseVolatileWrite_WithTrivia(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}, value As {{type}}) + ' Trivia prefix + {|#0:Thread.VolatileWrite(arg, value)|} ' Trivia infix + ' Trivia suffix + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}, value As {type}) + ' Trivia prefix + Volatile.Write(arg, value) ' Trivia infix + ' Trivia suffix + End Sub + End Class + """; + + return VerifyVisualBasicAsync(code, fixedCode); + } + private static Task VerifyCsharpAsync(string code, string fixedCode) { return new VerifyCS.Test @@ -527,7 +753,10 @@ private static Task VerifyCsharpAsync(string code, string fixedCode) { Sources = { fixedCode, CsharpSystemThreadingThread } }, - ExpectedDiagnostics = { new DiagnosticResult("SYSLIB0054", DiagnosticSeverity.Warning).WithLocation(0) }, + ExpectedDiagnostics = + { + new DiagnosticResult("SYSLIB0054", DiagnosticSeverity.Warning).WithLocation(0) + }, LanguageVersion = LanguageVersion.CSharp8, ReferenceAssemblies = ReferenceAssemblies.Net.Net50 }.RunAsync(); @@ -545,7 +774,10 @@ private static Task VerifyVisualBasicAsync(string code, string fixedCode) { Sources = { fixedCode, VisualBasicSystemThreadingThread } }, - ExpectedDiagnostics = { new DiagnosticResult("SYSLIB0054", DiagnosticSeverity.Warning).WithLocation(0) }, + ExpectedDiagnostics = + { + new DiagnosticResult("SYSLIB0054", DiagnosticSeverity.Warning).WithLocation(0) + }, ReferenceAssemblies = ReferenceAssemblies.Net.Net50 }.RunAsync(); } diff --git a/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb index 707c891e84..4631f3815a 100644 --- a/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb +++ b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb @@ -12,12 +12,12 @@ Namespace Microsoft.NetCore.VisualBasic.Analyzers.Usage Public NotInheritable Class BasicUseVolatileReadWriteFixer Inherits UseVolatileReadWriteFixer - Protected Overrides Function TryGetThreadVolatileReadWriteMemberAccess(invocation As SyntaxNode, methodName As String, ByRef memberAccess As SyntaxNode) As Boolean - memberAccess = Nothing + Protected Overrides Function TryGetThreadVolatileReadWriteArguments(invocation As SyntaxNode, methodName As String, ByRef arguments As IEnumerable(Of SyntaxNode)) As Boolean + arguments = Nothing Dim invocationExpression = TryCast(invocation, InvocationExpressionSyntax) Dim memberAccessExpression = TryCast(invocationExpression.Expression, MemberAccessExpressionSyntax) If memberAccessExpression IsNot Nothing AndAlso memberAccessExpression.Name.Identifier.Text = methodName - memberAccess = memberAccessExpression + arguments = invocationExpression.ArgumentList.Arguments.Select(Function(a) DirectCast(a, SimpleArgumentSyntax).WithNameColonEquals(Nothing)) Return True End If From 4ebbd2b23af2c13e765e93a25a4b1f7dd16c3c06 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Thu, 7 Mar 2024 18:25:22 +0100 Subject: [PATCH 07/10] Use IOperation API --- .../Usage/CSharpUseVolatileReadWriteFixer.cs | 34 +++-- .../Usage/UseVolatileReadWrite.Fixer.cs | 89 ++++++++---- .../Usage/UseVolatileReadWriteTests.cs | 134 +++++++++++++++++- .../Usage/BasicUseVolatileReadWriteFixer.vb | 30 ++-- src/Utilities/Compiler/WellKnownTypeNames.cs | 1 + 5 files changed, 238 insertions(+), 50 deletions(-) diff --git a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs index 55399ba0f3..086401c930 100644 --- a/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs +++ b/src/NetAnalyzers/CSharp/Microsoft.NetCore.Analyzers/Usage/CSharpUseVolatileReadWriteFixer.cs @@ -1,12 +1,13 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. using System.Collections.Generic; +using System.Collections.Immutable; using System.Composition; -using System.Diagnostics.CodeAnalysis; -using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Operations; using Microsoft.NetCore.Analyzers.Usage; namespace Microsoft.NetCore.CSharp.Analyzers.Usage @@ -14,17 +15,32 @@ namespace Microsoft.NetCore.CSharp.Analyzers.Usage [ExportCodeFixProvider(LanguageNames.CSharp), Shared] internal sealed class CSharpUseVolatileReadWriteFixer : UseVolatileReadWriteFixer { - protected override bool TryGetThreadVolatileReadWriteArguments(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out IEnumerable? arguments) + protected override SyntaxNode GetArgumentForVolatileReadCall(IArgumentOperation argument, IParameterSymbol volatileReadParameter) { - arguments = null; - if (invocation is InvocationExpressionSyntax { Expression: MemberAccessExpressionSyntax m } i && m.Name.Identifier.Text == methodName) + var argumentSyntax = (ArgumentSyntax)argument.Syntax; + if (argumentSyntax.NameColon is null) { - arguments = i.ArgumentList.Arguments.Select(a => a.WithNameColon(null)); - - return true; + return argumentSyntax; } - return false; + return argumentSyntax.WithNameColon(SyntaxFactory.NameColon(volatileReadParameter.Name)); + } + + protected override IEnumerable GetArgumentForVolatileWriteCall(ImmutableArray arguments, ImmutableArray volatileWriteParameters) + { + foreach (var argument in arguments) + { + var argumentSyntax = (ArgumentSyntax)argument.Syntax; + if (argumentSyntax.NameColon is null) + { + yield return argumentSyntax; + } + else + { + var parameterName = volatileWriteParameters[argument.Parameter!.Ordinal].Name; + yield return argumentSyntax.WithNameColon(SyntaxFactory.NameColon(parameterName)); + } + } } } } \ No newline at end of file diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs index 00bb42980e..3b051f2058 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs @@ -1,8 +1,9 @@ // 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.Generic; using System.Collections.Immutable; -using System.Diagnostics.CodeAnalysis; +using System.Linq; using System.Threading; using System.Threading.Tasks; using Analyzer.Utilities; @@ -10,6 +11,7 @@ using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Editing; +using Microsoft.CodeAnalysis.Operations; namespace Microsoft.NetCore.Analyzers.Usage { @@ -24,40 +26,75 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) { var root = await context.Document.GetRequiredSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); var node = root.FindNode(context.Span, getInnermostNodeForTie: true); - if (TryGetThreadVolatileReadWriteArguments(node, ThreadVolatileReadMethodName, out var arguments)) + var semanticModel = await context.Document.GetRequiredSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); + var typeProvider = WellKnownTypeProvider.GetOrCreate(semanticModel.Compilation); + var operation = semanticModel.GetOperation(node); + if (typeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingThread) is not INamedTypeSymbol threadType + || typeProvider.GetOrCreateTypeByMetadataName(WellKnownTypeNames.SystemThreadingVolatile) is not INamedTypeSymbol volatileType + || operation is not IInvocationOperation invocationOperation) { - var codeAction = CodeAction.Create( - MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle, - _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(node, CreateVolatileMemberAccess(context.Document, VolatileReadMethodName, arguments).WithTriviaFrom(node)))), - nameof(MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle) - ); - context.RegisterCodeFix(codeAction, context.Diagnostics); + return; } - else if (TryGetThreadVolatileReadWriteArguments(node, ThreadVolatileWriteMethodName, out arguments)) + + var obsoleteMethodsBuilder = ImmutableArray.CreateBuilder(); + obsoleteMethodsBuilder.AddRange(threadType.GetMembers(ThreadVolatileReadMethodName).OfType()); + obsoleteMethodsBuilder.AddRange(threadType.GetMembers(ThreadVolatileWriteMethodName).OfType()); + var obsoleteMethods = obsoleteMethodsBuilder.ToImmutable(); + + var volatileReadMethod = volatileType.GetMembers(VolatileReadMethodName).OfType().FirstOrDefault(); + var volatileWriteMethod = volatileType.GetMembers(VolatileWriteMethodName).OfType().FirstOrDefault(); + + if (!SymbolEqualityComparer.Default.Equals(invocationOperation.TargetMethod.ContainingType, threadType) + || !obsoleteMethods.Any(SymbolEqualityComparer.Default.Equals, invocationOperation.TargetMethod) + || volatileReadMethod is null + || volatileWriteMethod is null) { - var codeAction = CodeAction.Create( - MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle, - _ => Task.FromResult(context.Document.WithSyntaxRoot(root.ReplaceNode(node, CreateVolatileMemberAccess(context.Document, VolatileWriteMethodName, arguments).WithTriviaFrom(node)))), - nameof(MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle) - ); - context.RegisterCodeFix(codeAction, context.Diagnostics); + return; } - } - private static SyntaxNode CreateVolatileMemberAccess(Document document, string methodName, IEnumerable arguments) - { - var generator = SyntaxGenerator.GetGenerator(document); - var memberAccess = generator.MemberAccessExpression( - generator.IdentifierName(nameof(Volatile)), - generator.IdentifierName(methodName) - ); + var codeAction = CodeAction.Create( + MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle, + ReplaceObsoleteCall, + equivalenceKey: nameof(MicrosoftNetCoreAnalyzersResources.DoNotUseThreadVolatileReadWriteCodeFixTitle)); + + context.RegisterCodeFix(codeAction, context.Diagnostics); + + return; + + async Task ReplaceObsoleteCall(CancellationToken cancellationToken) + { + var editor = await DocumentEditor.CreateAsync(context.Document, cancellationToken).ConfigureAwait(false); + var generator = editor.Generator; + + string methodName; + IEnumerable arguments; + if (invocationOperation.TargetMethod.Name.Equals(ThreadVolatileReadMethodName, StringComparison.Ordinal)) + { + methodName = VolatileReadMethodName; + arguments = [GetArgumentForVolatileReadCall(invocationOperation.Arguments[0], volatileReadMethod.Parameters[0])]; + } + else + { + methodName = VolatileWriteMethodName; + arguments = GetArgumentForVolatileWriteCall(invocationOperation.Arguments, volatileWriteMethod.Parameters); + } + + var methodExpression = generator.MemberAccessExpression( + generator.TypeExpressionForStaticMemberAccess(volatileType), + methodName); + var methodInvocation = generator.InvocationExpression(methodExpression, arguments); + + editor.ReplaceNode(invocationOperation.Syntax, methodInvocation.WithTriviaFrom(invocationOperation.Syntax)); - return generator.InvocationExpression(memberAccess, arguments); + return context.Document.WithSyntaxRoot(editor.GetChangedRoot()); + } } - public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; + protected abstract SyntaxNode GetArgumentForVolatileReadCall(IArgumentOperation argument, IParameterSymbol volatileReadParameter); - protected abstract bool TryGetThreadVolatileReadWriteArguments(SyntaxNode invocation, string methodName, [NotNullWhen(true)] out IEnumerable? arguments); + protected abstract IEnumerable GetArgumentForVolatileWriteCall(ImmutableArray arguments, ImmutableArray volatileWriteParameters); + + public sealed override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer; public sealed override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create("SYSLIB0054"); } diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs index e27bc2e942..4bdc093a70 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -285,7 +285,7 @@ class Test { void M({{type}} arg) { - Volatile.Read(ref arg); + Volatile.Read(location: ref arg); } } """; @@ -455,7 +455,41 @@ class Test { void M({{type}} arg, {{type}} value) { - Volatile.Write(ref arg, value); + Volatile.Write(location: ref arg, value: value); + } + } + """; + + return VerifyCsharpAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(CSharpTypes))] + public Task CS_UseVolatileWrite_WithReversedArguments(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + {|#0:Thread.VolatileWrite(value: value, address: ref arg)|}; + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + Volatile.Write(value: value, location: ref arg); } } """; @@ -465,7 +499,41 @@ void M({{type}} arg, {{type}} value) [Theory] [MemberData(nameof(CSharpTypes))] - public Task CS_UseVolatileWrite_WithWrivia(string type) + public Task CS_UseVolatileWrite_WithSingleNamedArgument(string type) + { + var code = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + {|#0:Thread.VolatileWrite(address: ref arg, value)|}; + } + } + """; + var fixedCode = $$""" + using System; + using System.Threading; + + #nullable enable + class Test + { + void M({{type}} arg, {{type}} value) + { + Volatile.Write(location: ref arg, value); + } + } + """; + + return VerifyCsharpAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(CSharpTypes))] + public Task CS_UseVolatileWrite_WithTrivia(string type) { var code = $$""" using System; @@ -613,7 +681,7 @@ Imports System.Threading Class Test Sub M(arg As {type}) - Volatile.Read(arg) + Volatile.Read(location:=arg) End Sub End Class """; @@ -701,7 +769,63 @@ Imports System.Threading Class Test Sub M(arg As {type}, value As {type}) - Volatile.Write(arg, value) + Volatile.Write(location:=arg, value:=value) + End Sub + End Class + """; + + return VerifyVisualBasicAsync(code, fixedCode); + } + + [Theory(Skip = "Visual Basic's method arguments are not passed to the fixer in the order they are passed in code, so this does currently not work.")] + [MemberData(nameof(VisualBasicTypes))] + public Task VB_UseVolatileWrite_WithReversedArguments(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}, value As {{type}}) + {|#0:Thread.VolatileWrite(value:=value, address:=arg)|} + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}, value As {type}) + Volatile.Write(value:=value, location:=arg) + End Sub + End Class + """; + + return VerifyVisualBasicAsync(code, fixedCode); + } + + [Theory] + [MemberData(nameof(VisualBasicTypes))] + public Task VB_UseVolatileWrite_WithSingleNamedArgument(string type) + { + var code = $$""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {{type}}, value As {{type}}) + {|#0:Thread.VolatileWrite(address:=arg, value)|} + End Sub + End Class + """; + var fixedCode = $""" + Imports System + Imports System.Threading + + Class Test + Sub M(arg As {type}, value As {type}) + Volatile.Write(location:=arg, value) End Sub End Class """; diff --git a/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb index 4631f3815a..e9afa24dce 100644 --- a/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb +++ b/src/NetAnalyzers/VisualBasic/Microsoft.NetCore.Analyzers/Usage/BasicUseVolatileReadWriteFixer.vb @@ -1,9 +1,11 @@ ' Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. +Imports System.Collections.Immutable Imports System.Composition -Imports System.Runtime.InteropServices Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.CodeFixes +Imports Microsoft.CodeAnalysis.Operations +Imports Microsoft.CodeAnalysis.VisualBasic Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Microsoft.NetCore.Analyzers.Usage @@ -12,17 +14,25 @@ Namespace Microsoft.NetCore.VisualBasic.Analyzers.Usage Public NotInheritable Class BasicUseVolatileReadWriteFixer Inherits UseVolatileReadWriteFixer - Protected Overrides Function TryGetThreadVolatileReadWriteArguments(invocation As SyntaxNode, methodName As String, ByRef arguments As IEnumerable(Of SyntaxNode)) As Boolean - arguments = Nothing - Dim invocationExpression = TryCast(invocation, InvocationExpressionSyntax) - Dim memberAccessExpression = TryCast(invocationExpression.Expression, MemberAccessExpressionSyntax) - If memberAccessExpression IsNot Nothing AndAlso memberAccessExpression.Name.Identifier.Text = methodName - arguments = invocationExpression.ArgumentList.Arguments.Select(Function(a) DirectCast(a, SimpleArgumentSyntax).WithNameColonEquals(Nothing)) - - Return True + Protected Overrides Function GetArgumentForVolatileReadCall(argument As IArgumentOperation, volatileReadParameter as IParameterSymbol) As SyntaxNode + Dim argumentSyntax = DirectCast(argument.Syntax, SimpleArgumentSyntax) + If argumentSyntax.NameColonEquals Is Nothing Then + Return argumentSyntax End If - Return False + Return argumentSyntax.WithNameColonEquals(SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName(volatileReadParameter.Name))) + End Function + + Protected Overrides Iterator Function GetArgumentForVolatileWriteCall(arguments As ImmutableArray(Of IArgumentOperation), volatileWriteParameters As ImmutableArray(Of IParameterSymbol)) As IEnumerable(Of SyntaxNode) + For Each argument In arguments + Dim argumentSyntax = DirectCast(argument.Syntax, SimpleArgumentSyntax) + If argumentSyntax.NameColonEquals Is Nothing Then + Yield argumentSyntax + Else + Dim parameterName = volatileWriteParameters(argument.Parameter.Ordinal).Name + Yield argumentSyntax.WithNameColonEquals(SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName(parameterName))) + End If + Next End Function End Class diff --git a/src/Utilities/Compiler/WellKnownTypeNames.cs b/src/Utilities/Compiler/WellKnownTypeNames.cs index b85343f7e6..9433ed1078 100644 --- a/src/Utilities/Compiler/WellKnownTypeNames.cs +++ b/src/Utilities/Compiler/WellKnownTypeNames.cs @@ -439,6 +439,7 @@ internal static class WellKnownTypeNames public const string SystemThreadingTasksValueTask = "System.Threading.Tasks.ValueTask"; public const string SystemThreadingTasksValueTask1 = "System.Threading.Tasks.ValueTask`1"; public const string SystemThreadingThread = "System.Threading.Thread"; + public const string SystemThreadingVolatile = "System.Threading.Volatile"; public const string SystemTimeSpan = "System.TimeSpan"; public const string SystemType = "System.Type"; public const string SystemUri = "System.Uri"; From 7c117bd5d8ab3054720383762c47352fffb5b240 Mon Sep 17 00:00:00 2001 From: Collin Alpert Date: Mon, 11 Mar 2024 20:57:43 +0100 Subject: [PATCH 08/10] Provide arguments in parameter order. --- .../Usage/UseVolatileReadWrite.Fixer.cs | 3 ++- .../Usage/UseVolatileReadWriteTests.cs | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs index 3b051f2058..6d8234a735 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs @@ -7,6 +7,7 @@ using System.Threading; using System.Threading.Tasks; using Analyzer.Utilities; +using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; @@ -76,7 +77,7 @@ async Task ReplaceObsoleteCall(CancellationToken cancellationToken) else { methodName = VolatileWriteMethodName; - arguments = GetArgumentForVolatileWriteCall(invocationOperation.Arguments, volatileWriteMethod.Parameters); + arguments = GetArgumentForVolatileWriteCall(invocationOperation.Arguments.GetArgumentsInParameterOrder(), volatileWriteMethod.Parameters); } var methodExpression = generator.MemberAccessExpression( diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs index 4bdc093a70..fb9004e070 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -489,7 +489,7 @@ class Test { void M({{type}} arg, {{type}} value) { - Volatile.Write(value: value, location: ref arg); + Volatile.Write(location: ref arg, value: value); } } """; @@ -777,7 +777,7 @@ End Class return VerifyVisualBasicAsync(code, fixedCode); } - [Theory(Skip = "Visual Basic's method arguments are not passed to the fixer in the order they are passed in code, so this does currently not work.")] + [Theory] [MemberData(nameof(VisualBasicTypes))] public Task VB_UseVolatileWrite_WithReversedArguments(string type) { @@ -797,7 +797,7 @@ Imports System.Threading Class Test Sub M(arg As {type}, value As {type}) - Volatile.Write(value:=value, location:=arg) + Volatile.Write(location:=arg, value:=value) End Sub End Class """; From bd93b3523da438ff5919202df3c25cb19f84d8d4 Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 11 Mar 2024 16:45:31 -0700 Subject: [PATCH 09/10] Revert "Provide arguments in parameter order." --- .../Usage/UseVolatileReadWrite.Fixer.cs | 3 +-- .../Usage/UseVolatileReadWriteTests.cs | 6 +++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs index 6d8234a735..3b051f2058 100644 --- a/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs +++ b/src/NetAnalyzers/Core/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWrite.Fixer.cs @@ -7,7 +7,6 @@ using System.Threading; using System.Threading.Tasks; using Analyzer.Utilities; -using Analyzer.Utilities.Extensions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; using Microsoft.CodeAnalysis.CodeFixes; @@ -77,7 +76,7 @@ async Task ReplaceObsoleteCall(CancellationToken cancellationToken) else { methodName = VolatileWriteMethodName; - arguments = GetArgumentForVolatileWriteCall(invocationOperation.Arguments.GetArgumentsInParameterOrder(), volatileWriteMethod.Parameters); + arguments = GetArgumentForVolatileWriteCall(invocationOperation.Arguments, volatileWriteMethod.Parameters); } var methodExpression = generator.MemberAccessExpression( diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs index fb9004e070..4bdc093a70 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -489,7 +489,7 @@ class Test { void M({{type}} arg, {{type}} value) { - Volatile.Write(location: ref arg, value: value); + Volatile.Write(value: value, location: ref arg); } } """; @@ -777,7 +777,7 @@ End Class return VerifyVisualBasicAsync(code, fixedCode); } - [Theory] + [Theory(Skip = "Visual Basic's method arguments are not passed to the fixer in the order they are passed in code, so this does currently not work.")] [MemberData(nameof(VisualBasicTypes))] public Task VB_UseVolatileWrite_WithReversedArguments(string type) { @@ -797,7 +797,7 @@ Imports System.Threading Class Test Sub M(arg As {type}, value As {type}) - Volatile.Write(location:=arg, value:=value) + Volatile.Write(value:=value, location:=arg) End Sub End Class """; From 8284db4aa5bd1d4166126a9c92bfd3cbc4c01f5a Mon Sep 17 00:00:00 2001 From: Buyaa Namnan Date: Mon, 11 Mar 2024 16:46:39 -0700 Subject: [PATCH 10/10] Enable reverse order test in VB --- .../Usage/UseVolatileReadWriteTests.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs index 4bdc093a70..366b746cc5 100644 --- a/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs +++ b/src/NetAnalyzers/UnitTests/Microsoft.NetCore.Analyzers/Usage/UseVolatileReadWriteTests.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the MIT license. See License.txt in the project root for license information. using System.Threading.Tasks; using Microsoft.CodeAnalysis; @@ -777,7 +777,7 @@ End Class return VerifyVisualBasicAsync(code, fixedCode); } - [Theory(Skip = "Visual Basic's method arguments are not passed to the fixer in the order they are passed in code, so this does currently not work.")] + [Theory] [MemberData(nameof(VisualBasicTypes))] public Task VB_UseVolatileWrite_WithReversedArguments(string type) { @@ -797,7 +797,7 @@ Imports System.Threading Class Test Sub M(arg As {type}, value As {type}) - Volatile.Write(value:=value, location:=arg) + Volatile.Write(location:=arg, value:=value) End Sub End Class """;