Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Override Stream ReadAsync/WriteAsync Analyzer #4725

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
98dbbde
Implement Prefer IsKind analyzer
sharwell Apr 22, 2020
0b7c5bf
Merge remote-tracking branch 'upstream/master' into merges/master-to-…
mavasani Dec 4, 2020
05073cd
Update auto-generated documentation file
mavasani Dec 4, 2020
73a1018
Merge pull request #4497 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 4, 2020
16b39be
Merge pull request #4512 from dotnet/merges/master-to-release/6.0.1xx…
jmarolf Dec 7, 2020
522c99d
Merge pull request #4523 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 7, 2020
1bba866
Merge branch 'release/6.0.1xx-preview1' into merges/master-to-release…
mavasani Dec 7, 2020
efab9f7
Merge pull request #4525 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 7, 2020
f83295a
Remove rule CA1801 - replaced by IDE0060
Evangelink Dec 8, 2020
1c852e3
Add CA1801 to removed rules list
Evangelink Dec 9, 2020
7f39ec8
Fix md and sarif files
Evangelink Dec 9, 2020
d5f25ec
Merge pull request #4535 from Evangelink/remove-CA1801
mavasani Dec 9, 2020
3f7c3d1
Merge remote-tracking branch 'upstream/master' into merges/master-to-…
mavasani Dec 16, 2020
0ecfcaf
Merge pull request #4527 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 16, 2020
e389e38
Merge pull request #4581 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 16, 2020
b5237fc
Merge pull request #4585 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 17, 2020
ace3839
Merge remote-tracking branch 'upstream/master' into merges/master-to-…
mavasani Dec 18, 2020
34f2b02
Merge pull request #4588 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 18, 2020
c742b24
Merge pull request #4606 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 18, 2020
14b0d28
Merge pull request #4607 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 19, 2020
a6f1e33
Merge pull request #4611 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 20, 2020
a7dc117
Merge pull request #4612 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Dec 20, 2020
fe6d6b0
Merge pull request #4616 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 4, 2021
dcd310d
Merge remote-tracking branch 'upstream/master' into merges/master-to-…
mavasani Jan 4, 2021
461d828
Merge pull request #4661 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 4, 2021
dbd14e1
Merge pull request #4663 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 5, 2021
a807305
Merge remote-tracking branch 'upstream/master' into merges/master-to-…
mavasani Jan 5, 2021
01aaa83
Merge pull request #4668 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 5, 2021
cd686f3
Merge branch 'release/6.0.1xx-preview1' into merges/master-to-release…
mavasani Jan 5, 2021
f935ee7
Merge pull request #4671 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 5, 2021
bb764b5
Merge pull request #4675 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 7, 2021
202c1ed
Remove single-file analyzer
Jan 8, 2021
1841008
Merge branch 'release/6.0.1xx-preview1' into remove-sf-analyzer
mavasani Jan 11, 2021
89f58a2
Update src/NetAnalyzers/Core/AnalyzerReleases.Unshipped.md
mavasani Jan 11, 2021
c498fc5
Merge pull request #4680 from mateoatr/remove-sf-analyzer
mavasani Jan 11, 2021
d9836de
Merge pull request #4684 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 11, 2021
87cb749
Merge pull request #4685 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 11, 2021
b949ee9
Merge remote-tracking branch 'dotnet/master' into prefer-iskind
sharwell Jan 12, 2021
049c59c
Merge branch 'release/6.0.1xx-preview1' into merges/master-to-release…
mavasani Jan 12, 2021
1691413
Merge pull request #4686 from dotnet/merges/master-to-release/6.0.1xx…
mavasani Jan 12, 2021
fc2dd9d
Update messages for Prefer IsKind analyzer
sharwell Jan 12, 2021
a67832e
Implement analyzer with basic tests
NewellClark Jan 15, 2021
fbc706d
Added more tests
NewellClark Jan 17, 2021
c480509
Merge pull request #3537 from sharwell/prefer-iskind
sharwell Jan 20, 2021
33582d0
Ensure CA1835 preserves nullability (#4664)
carlossanlop Jan 20, 2021
0e64ed1
Revert workaround for old SyntaxGenerator bug
Youssef1313 Jan 20, 2021
234910a
Fix references to fixer in tests
Youssef1313 Jan 20, 2021
b0c80e4
Make all rules warning for RulesetKind.AllEnabled
Youssef1313 Jan 21, 2021
a6e6317
Update Program.cs
Youssef1313 Jan 21, 2021
516eea0
Make similar change for CustomTagEnabled and CategoryEnabled
Youssef1313 Jan 21, 2021
26c3ce4
Merge pull request #4720 from Youssef1313/remove-workaround
mavasani Jan 21, 2021
14fd5ef
Merge pull request #4724 from Youssef1313/patch-1
mavasani Jan 21, 2021
8b9cf92
Add ProvideStreamMemoryBasedAsyncOverrides analyzer
NewellClark Jan 21, 2021
d958c67
Merge remote-tracking branch 'dotnet/master' into issue-33789
NewellClark Jan 21, 2021
f732671
Ran msbuild
NewellClark Jan 21, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<PropertyGroup>
<VersionPrefix>3.3.3</VersionPrefix>
<PreReleaseVersionLabel>beta1</PreReleaseVersionLabel>
<NetAnalyzersVersionPrefix>5.0.4</NetAnalyzersVersionPrefix>
<NetAnalyzersVersionPrefix>6.0.0</NetAnalyzersVersionPrefix>
<NetAnalyzersPreReleaseVersionLabel>preview1</NetAnalyzersPreReleaseVersionLabel>
<AnalyzerUtilitiesVersionPrefix>$(VersionPrefix)</AnalyzerUtilitiesVersionPrefix>
<!--
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Composition;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers.Fixers;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.CSharp.Analyzers.MetaAnalyzers.Fixers
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CSharpPreferIsKindFix))]
[Shared]
public sealed class CSharpPreferIsKindFix : PreferIsKindFix
{
protected override async Task<Document> ConvertKindToIsKindAsync(Document document, TextSpan sourceSpan, CancellationToken cancellationToken)
{
var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var binaryExpression = root.FindNode(sourceSpan, getInnermostNodeForTie: true).FirstAncestorOrSelf<BinaryExpressionSyntax>();

if (binaryExpression.Left is not InvocationExpressionSyntax invocation)
{
return document;
}

var newInvocation = invocation
.WithExpression(ConvertKindNameToIsKind(invocation.Expression))
.AddArgumentListArguments(SyntaxFactory.Argument(binaryExpression.Right.WithoutTrailingTrivia()))
.WithTrailingTrivia(binaryExpression.Right.GetTrailingTrivia());
var negate = binaryExpression.OperatorToken.IsKind(SyntaxKind.ExclamationEqualsToken);
SyntaxNode newRoot;
if (negate)
{
newRoot = root.ReplaceNode(binaryExpression, SyntaxFactory.PrefixUnaryExpression(SyntaxKind.LogicalNotExpression, newInvocation.WithoutLeadingTrivia()).WithLeadingTrivia(newInvocation.GetLeadingTrivia()));
}
else
{
newRoot = root.ReplaceNode(binaryExpression, newInvocation);
}

return document.WithSyntaxRoot(newRoot);
}

private static ExpressionSyntax ConvertKindNameToIsKind(ExpressionSyntax expression)
{
if (expression is MemberAccessExpressionSyntax memberAccessExpression)
{
return memberAccessExpression.WithName(SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("IsKind")));
}
else
{
return expression;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
; Please do not edit this file manually, it should only be updated through code fix application.

### New Rules
Rule ID | Category | Severity | Notes
--------|----------|----------|-------
RS1034 | MicrosoftCodeAnalysisPerformance | Warning | PreferIsKindAnalyzer
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema

<!--
Microsoft ResX Schema
Version 2.0

The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.

Example:

... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
Expand All @@ -26,36 +26,36 @@
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>

There are any number of "resheader" rows that contain simple
There are any number of "resheader" rows that contain simple
name/value pairs.

Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.

The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:

Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.

mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.

mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
Expand Down Expand Up @@ -517,4 +517,16 @@
<data name="CompareSymbolsCorrectlyDescriptionGetHashCode" xml:space="preserve">
<value>Symbols should be compared for equality, not identity. An explicit call to 'GetHashCode' will likely result in the wrong behavior.</value>
</data>
<data name="PreferIsKindDescription" xml:space="preserve">
<value>Prefer 'syntax.IsKind(kind)' to 'syntax.Kind() == kind' when checking syntax kinds. Code using 'IsKind' is slightly more efficient at runtime, so consistent use of this form where applicable helps improve performance in complex analysis scenarios.</value>
</data>
<data name="PreferIsKindMessage" xml:space="preserve">
<value>Prefer 'IsKind' for checking syntax kinds</value>
</data>
<data name="PreferIsKindTitle" xml:space="preserve">
<value>Prefer 'IsKind' for checking syntax kinds</value>
</data>
<data name="PreferIsKindFix" xml:space="preserve">
<value>Use 'IsKind' instead of 'Kind'</value>
</data>
</root>
1 change: 1 addition & 0 deletions src/Microsoft.CodeAnalysis.Analyzers/Core/DiagnosticIds.cs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ internal static class DiagnosticIds
public const string DefineDiagnosticTitleCorrectlyRuleId = "RS1031";
public const string DefineDiagnosticMessageCorrectlyRuleId = "RS1032";
public const string DefineDiagnosticDescriptionCorrectlyRuleId = "RS1033";
public const string PreferIsKindRuleId = "RS1034";

// Release tracking analyzer IDs
public const string DeclareDiagnosticIdInAnalyzerReleaseRuleId = "RS2000";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Immutable;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.Text;

namespace Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers.Fixers
{
public abstract class PreferIsKindFix : CodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds => ImmutableArray.Create(PreferIsKindAnalyzer.Rule.Id);

public override FixAllProvider GetFixAllProvider()
=> WellKnownFixAllProviders.BatchFixer;

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
foreach (var diagnostic in context.Diagnostics)
{
context.RegisterCodeFix(
CodeAction.Create(
CodeAnalysisDiagnosticsResources.PreferIsKindFix,
cancellationToken => ConvertKindToIsKindAsync(context.Document, diagnostic.Location.SourceSpan, cancellationToken),
equivalenceKey: nameof(PreferIsKindFix)),
diagnostic);
}

return Task.CompletedTask;
}

protected abstract Task<Document> ConvertKindToIsKindAsync(Document document, TextSpan sourceSpan, CancellationToken cancellationToken);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Collections.Generic;
using System.Collections.Immutable;
using Analyzer.Utilities;
using Analyzer.Utilities.Extensions;
using Microsoft.CodeAnalysis.Diagnostics;
using Microsoft.CodeAnalysis.Operations;

namespace Microsoft.CodeAnalysis.Analyzers.MetaAnalyzers
{
[DiagnosticAnalyzer(LanguageNames.CSharp, LanguageNames.VisualBasic)]
public sealed class PreferIsKindAnalyzer : DiagnosticAnalyzer
{
private static readonly LocalizableString s_localizableTitle = new LocalizableResourceString(nameof(CodeAnalysisDiagnosticsResources.PreferIsKindTitle), CodeAnalysisDiagnosticsResources.ResourceManager, typeof(CodeAnalysisDiagnosticsResources));
private static readonly LocalizableString s_localizableMessage = new LocalizableResourceString(nameof(CodeAnalysisDiagnosticsResources.PreferIsKindMessage), CodeAnalysisDiagnosticsResources.ResourceManager, typeof(CodeAnalysisDiagnosticsResources));
private static readonly LocalizableString s_localizableDescription = new LocalizableResourceString(nameof(CodeAnalysisDiagnosticsResources.PreferIsKindDescription), CodeAnalysisDiagnosticsResources.ResourceManager, typeof(CodeAnalysisDiagnosticsResources));

internal static DiagnosticDescriptor Rule = new(
DiagnosticIds.PreferIsKindRuleId,
s_localizableTitle,
s_localizableMessage,
DiagnosticCategory.MicrosoftCodeAnalysisPerformance,
DiagnosticSeverity.Warning,
isEnabledByDefault: true,
description: s_localizableDescription,
helpLinkUri: null,
customTags: WellKnownDiagnosticTags.Telemetry);

public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);

public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

context.RegisterCompilationStartAction(context =>
{
// Kind() methods
// Microsoft.CodeAnalysis.CSharp.CSharpExtensions.Kind
// Microsoft.CodeAnalysis.VisualBasic.VisualBasicExtensions.Kind
//
// IsKind() methods
// Microsoft.CodeAnalysis.CSharpExtensions.IsKind
// Microsoft.CodeAnalysis.VisualBasicExtensions.IsKind

Dictionary<INamedTypeSymbol, INamedTypeSymbol> containingTypeMap = new Dictionary<INamedTypeSymbol, INamedTypeSymbol>();
if (context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftCodeAnalysisCSharpCSharpExtensions) is { } csharpKindExtensions
&& context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftCodeAnalysisCSharpExtensions) is { } csharpIsKindExtensions)
{
containingTypeMap[csharpKindExtensions] = csharpIsKindExtensions;
}

if (context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftCodeAnalysisVisualBasicVisualBasicExtensions) is { } vbKindExtensions
&& context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.MicrosoftCodeAnalysisVisualBasicExtensions) is { } vbIsKindExtensions)
{
containingTypeMap[vbKindExtensions] = vbIsKindExtensions;
}

if (containingTypeMap.Count > 0)
{
context.RegisterOperationAction(context => HandleBinaryOperation(context, containingTypeMap), OperationKind.Binary);
}
});
}

private static void HandleBinaryOperation(OperationAnalysisContext context, Dictionary<INamedTypeSymbol, INamedTypeSymbol> containingTypeMap)
{
var operation = (IBinaryOperation)context.Operation;
if (operation.OperatorKind is not (BinaryOperatorKind.Equals or BinaryOperatorKind.NotEquals))
{
return;
}

if (operation.LeftOperand.WalkDownConversion() is IInvocationOperation { TargetMethod: { Name: "Kind", ContainingType: var containingType } }
&& containingTypeMap.TryGetValue(containingType, out _))
{
context.ReportDiagnostic(operation.LeftOperand.CreateDiagnostic(Rule));
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,26 @@
<target state="translated">Při registraci analyzátoru syntaxe, symbolů nebo operací musíte zadat minimálně jeden druh syntaxe, symbolu nebo operace. V opačném případě se registrovaná akce nikdy při analýze nevyvolá.</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindDescription">
<source>Prefer 'syntax.IsKind(kind)' to 'syntax.Kind() == kind' when checking syntax kinds. Code using 'IsKind' is slightly more efficient at runtime, so consistent use of this form where applicable helps improve performance in complex analysis scenarios.</source>
<target state="new">Prefer 'syntax.IsKind(kind)' to 'syntax.Kind() == kind' when checking syntax kinds. Code using 'IsKind' is slightly more efficient at runtime, so consistent use of this form where applicable helps improve performance in complex analysis scenarios.</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindFix">
<source>Use 'IsKind' instead of 'Kind'</source>
<target state="new">Use 'IsKind' instead of 'Kind'</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindMessage">
<source>Prefer 'IsKind' for checking syntax kinds</source>
<target state="new">Prefer 'IsKind' for checking syntax kinds</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindTitle">
<source>Prefer 'IsKind' for checking syntax kinds</source>
<target state="new">Prefer 'IsKind' for checking syntax kinds</target>
<note />
</trans-unit>
<trans-unit id="ProvideCustomTagsInDescriptorDescription">
<source>The 'customTags' value is used as a way to enable specific actions and filters on diagnostic descriptors based on the specific values of the tags. Every Roslyn analyzer should have at least one tag from the 'WellKnownDiagnosticTags' class.</source>
<target state="translated">Hodnota customTags se používá jako způsob, jak povolit konkrétní akce a filtry v diagnostických popisovačích na základě konkrétních hodnot značek. Každý analyzátor Roslyn by měl mít alespoň jednu značku z třídy WellKnownDiagnosticTags.</target>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,26 @@
<target state="translated">Sie müssen mindestens eine Variante für Syntax, Symbol oder Vorgang angeben, wenn Sie eine Syntax-, Symbol- oder Vorgangsanalyseaktion registrieren. Andernfalls wird die registrierte Aktion während der Analyse nicht aufgerufen.</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindDescription">
<source>Prefer 'syntax.IsKind(kind)' to 'syntax.Kind() == kind' when checking syntax kinds. Code using 'IsKind' is slightly more efficient at runtime, so consistent use of this form where applicable helps improve performance in complex analysis scenarios.</source>
<target state="new">Prefer 'syntax.IsKind(kind)' to 'syntax.Kind() == kind' when checking syntax kinds. Code using 'IsKind' is slightly more efficient at runtime, so consistent use of this form where applicable helps improve performance in complex analysis scenarios.</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindFix">
<source>Use 'IsKind' instead of 'Kind'</source>
<target state="new">Use 'IsKind' instead of 'Kind'</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindMessage">
<source>Prefer 'IsKind' for checking syntax kinds</source>
<target state="new">Prefer 'IsKind' for checking syntax kinds</target>
<note />
</trans-unit>
<trans-unit id="PreferIsKindTitle">
<source>Prefer 'IsKind' for checking syntax kinds</source>
<target state="new">Prefer 'IsKind' for checking syntax kinds</target>
<note />
</trans-unit>
<trans-unit id="ProvideCustomTagsInDescriptorDescription">
<source>The 'customTags' value is used as a way to enable specific actions and filters on diagnostic descriptors based on the specific values of the tags. Every Roslyn analyzer should have at least one tag from the 'WellKnownDiagnosticTags' class.</source>
<target state="translated">Der Wert "customTags" wird verwendet, um bestimmte Aktionen und Filter für Diagnosedeskriptoren basierend auf den spezifischen Werten der Tags zu aktivieren. Jedes Roslyn-Analysetool muss mindestens ein Tag aus der Klasse "WellKnownDiagnosticTags" aufweisen.</target>
Expand Down
Loading