From dc3733fd582414524716fd25ad462d7a424ba5d7 Mon Sep 17 00:00:00 2001 From: Mihaly Marton Date: Sun, 28 Apr 2019 12:36:04 -0600 Subject: [PATCH] Resurrected the option to suppress in source using attributes (see https://github.com/dotnet/roslyn/issues/17218) The code was taken from the history (https://github.com/dotnet/roslyn/tree/4dfefe7b49c33d1d078494d52a84b16772158b11) and adapted to latest changes. TODO: * add unit tests * title needs translation --- .../CSharpSuppressionCodeFixProvider.cs | 65 ++++++++++++++----- ...Provider.LocalSuppressMessageCodeAction.cs | 42 ++++++++++++ .../AbstractSuppressionCodeFixProvider.cs | 12 +++- .../Portable/FeaturesResources.Designer.cs | 9 +++ .../Core/Portable/FeaturesResources.resx | 3 + .../Portable/xlf/FeaturesResources.cs.xlf | 5 ++ .../Portable/xlf/FeaturesResources.de.xlf | 5 ++ .../Portable/xlf/FeaturesResources.es.xlf | 5 ++ .../Portable/xlf/FeaturesResources.fr.xlf | 5 ++ .../Portable/xlf/FeaturesResources.it.xlf | 5 ++ .../Portable/xlf/FeaturesResources.ja.xlf | 5 ++ .../Portable/xlf/FeaturesResources.ko.xlf | 5 ++ .../Portable/xlf/FeaturesResources.pl.xlf | 5 ++ .../Portable/xlf/FeaturesResources.pt-BR.xlf | 5 ++ .../Portable/xlf/FeaturesResources.ru.xlf | 5 ++ .../Portable/xlf/FeaturesResources.tr.xlf | 5 ++ .../xlf/FeaturesResources.zh-Hans.xlf | 5 ++ .../xlf/FeaturesResources.zh-Hant.xlf | 5 ++ .../VisualBasicSuppressionCodeFixProvider.vb | 34 ++++++---- 19 files changed, 202 insertions(+), 28 deletions(-) create mode 100644 src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.LocalSuppressMessageCodeAction.cs diff --git a/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs b/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs index e70127dfef0..a6d0a256c86 100644 --- a/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs +++ b/src/Features/CSharp/Portable/CodeFixes/Suppression/CSharpSuppressionCodeFixProvider.cs @@ -87,23 +87,55 @@ protected override SyntaxNode AddGlobalSuppressMessageAttribute(SyntaxNode newRo var leadingTriviaForAttributeList = isFirst && !compilationRoot.HasLeadingTrivia ? SyntaxFactory.TriviaList(SyntaxFactory.Comment(GlobalSuppressionsFileHeaderComment)) : default; - var attributeList = CreateAttributeList(targetSymbol, diagnostic, leadingTrivia: leadingTriviaForAttributeList, needsLeadingEndOfLine: !isFirst); + var attributeList = CreateAttributeList(targetSymbol, diagnostic, isAssemblyAttribute: true, leadingTrivia: leadingTriviaForAttributeList, needsLeadingEndOfLine: !isFirst); attributeList = (AttributeListSyntax)Formatter.Format(attributeList, workspace, cancellationToken: cancellationToken); return compilationRoot.AddAttributeLists(attributeList); } + protected override SyntaxNode AddLocalSuppressMessageAttribute(SyntaxNode targetNode, ISymbol targetSymbol, Diagnostic diagnostic) + { + var memberNode = (MemberDeclarationSyntax)targetNode; + + SyntaxTriviaList leadingTriviaForAttributeList; + bool needsLeadingEndOfLine; + if (!memberNode.GetAttributes().Any()) + { + leadingTriviaForAttributeList = memberNode.GetLeadingTrivia(); + memberNode = memberNode.WithoutLeadingTrivia(); + needsLeadingEndOfLine = !leadingTriviaForAttributeList.Any() || !IsEndOfLine(leadingTriviaForAttributeList.Last()); + } + else + { + leadingTriviaForAttributeList = default(SyntaxTriviaList); + needsLeadingEndOfLine = true; + } + + var attributeList = CreateAttributeList(targetSymbol, diagnostic, isAssemblyAttribute: false, leadingTrivia: leadingTriviaForAttributeList, needsLeadingEndOfLine: needsLeadingEndOfLine); + return memberNode.AddAttributeLists(attributeList); + } + private AttributeListSyntax CreateAttributeList( ISymbol targetSymbol, Diagnostic diagnostic, + bool isAssemblyAttribute, SyntaxTriviaList leadingTrivia, bool needsLeadingEndOfLine) { - var attributeArguments = CreateAttributeArguments(targetSymbol, diagnostic); + var attributeArguments = CreateAttributeArguments(targetSymbol, diagnostic, isAssemblyAttribute); var attribute = SyntaxFactory.Attribute(SyntaxFactory.ParseName(SuppressMessageAttributeName), attributeArguments); var attributes = new SeparatedSyntaxList().Add(attribute); - var targetSpecifier = SyntaxFactory.AttributeTargetSpecifier(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)); - var attributeList = SyntaxFactory.AttributeList(targetSpecifier, attributes); + AttributeListSyntax attributeList; + if (isAssemblyAttribute) + { + var targetSpecifier = SyntaxFactory.AttributeTargetSpecifier(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)); + attributeList = SyntaxFactory.AttributeList(targetSpecifier, attributes); + } + else + { + attributeList = SyntaxFactory.AttributeList(attributes); + } + var endOfLineTrivia = SyntaxFactory.ElasticCarriageReturnLineFeed; var triviaList = SyntaxFactory.TriviaList(); @@ -115,7 +147,7 @@ protected override SyntaxNode AddGlobalSuppressMessageAttribute(SyntaxNode newRo return attributeList.WithLeadingTrivia(leadingTrivia.AddRange(triviaList)); } - private AttributeArgumentListSyntax CreateAttributeArguments(ISymbol targetSymbol, Diagnostic diagnostic) + private AttributeArgumentListSyntax CreateAttributeArguments(ISymbol targetSymbol, Diagnostic diagnostic, bool isAssemblyAttribute) { // SuppressMessage("Rule Category", "Rule Id", Justification = nameof(Justification), Scope = nameof(Scope), Target = nameof(Target)) var category = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(diagnostic.Descriptor.Category)); @@ -131,17 +163,20 @@ private AttributeArgumentListSyntax CreateAttributeArguments(ISymbol targetSymbo var attributeArgumentList = SyntaxFactory.AttributeArgumentList().AddArguments(categoryArgument, ruleIdArgument, justificationArgument); - var scopeString = GetScopeString(targetSymbol.Kind); - if (scopeString != null) + if (isAssemblyAttribute) { - var scopeExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(scopeString)); - var scopeArgument = SyntaxFactory.AttributeArgument(SyntaxFactory.NameEquals("Scope"), nameColon: null, expression: scopeExpr); - - var targetString = GetTargetString(targetSymbol); - var targetExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(targetString)); - var targetArgument = SyntaxFactory.AttributeArgument(SyntaxFactory.NameEquals("Target"), nameColon: null, expression: targetExpr); - - attributeArgumentList = attributeArgumentList.AddArguments(scopeArgument, targetArgument); + var scopeString = GetScopeString(targetSymbol.Kind); + if (scopeString != null) + { + var scopeExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(scopeString)); + var scopeArgument = SyntaxFactory.AttributeArgument(SyntaxFactory.NameEquals("Scope"), nameColon: null, expression: scopeExpr); + + var targetString = GetTargetString(targetSymbol); + var targetExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(targetString)); + var targetArgument = SyntaxFactory.AttributeArgument(SyntaxFactory.NameEquals("Target"), nameColon: null, expression: targetExpr); + + attributeArgumentList = attributeArgumentList.AddArguments(scopeArgument, targetArgument); + } } return attributeArgumentList; diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.LocalSuppressMessageCodeAction.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.LocalSuppressMessageCodeAction.cs new file mode 100644 index 00000000000..c2f48e475f1 --- /dev/null +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.LocalSuppressMessageCodeAction.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis.CodeActions; + +namespace Microsoft.CodeAnalysis.CodeFixes.Suppression +{ + internal abstract partial class AbstractSuppressionCodeFixProvider : ISuppressionFixProvider + { + internal sealed class LocalSuppressMessageCodeAction : AbstractSuppressionCodeAction + { + private readonly AbstractSuppressionCodeFixProvider _fixer; + private readonly ISymbol _targetSymbol; + private readonly SyntaxNode _targetNode; + private readonly Document _document; + private readonly Diagnostic _diagnostic; + + public LocalSuppressMessageCodeAction(AbstractSuppressionCodeFixProvider fixer, ISymbol targetSymbol, SyntaxNode targetNode, Document document, Diagnostic diagnostic) + : base(fixer, FeaturesResources.in_Source_attribute) + { + _fixer = fixer; + _targetSymbol = targetSymbol; + _targetNode = targetNode; + _document = document; + _diagnostic = diagnostic; + } + + protected async override Task GetChangedDocumentAsync(CancellationToken cancellationToken) + { + var newTargetNode = _fixer.AddLocalSuppressMessageAttribute(_targetNode, _targetSymbol, _diagnostic); + var root = await _document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); + var newRoot = root.ReplaceNode(_targetNode, newTargetNode); + return _document.WithSyntaxRoot(newRoot); + } + + protected override string DiagnosticIdForEquivalenceKey => _diagnostic.Id; + + internal SyntaxNode TargetNode_TestOnly => _targetNode; + } + } +} diff --git a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs index 81a21650e98..91e7edc66db 100644 --- a/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs +++ b/src/Features/Core/Portable/CodeFixes/Suppression/AbstractSuppressionCodeFixProvider.cs @@ -45,6 +45,7 @@ public bool CanBeSuppressedOrUnsuppressed(Diagnostic diagnostic) protected abstract SyntaxTriviaList CreatePragmaRestoreDirectiveTrivia(Diagnostic diagnostic, Func formatNode, bool needsLeadingEndOfLine, bool needsTrailingEndOfLine); protected abstract SyntaxNode AddGlobalSuppressMessageAttribute(SyntaxNode newRoot, ISymbol targetSymbol, Diagnostic diagnostic, Workspace workspace, CancellationToken cancellationToken); + protected abstract SyntaxNode AddLocalSuppressMessageAttribute(SyntaxNode targetNode, ISymbol targetSymbol, Diagnostic diagnostic); protected abstract string DefaultFileExtension { get; } protected abstract string SingleLineCommentStart { get; } @@ -152,6 +153,14 @@ internal async Task> GetPragmaSuppressio { // global assembly-level suppress message attribute. nestedActions.Add(new GlobalSuppressMessageCodeAction(suppressionTargetInfo.TargetSymbol, project, diagnostic, this)); + + // local suppress message attribute + // please note that in order to avoid issues with exising unit tests referencing the code fix + // by their index this needs to be the last added to nestedActions + if (suppressionTargetInfo.TargetMemberNode != null && suppressionTargetInfo.TargetSymbol.Kind != SymbolKind.Namespace) + { + nestedActions.Add(new LocalSuppressMessageCodeAction(this, suppressionTargetInfo.TargetSymbol, suppressionTargetInfo.TargetMemberNode, documentOpt, diagnostic)); + } } if (nestedActions.Count > 0) @@ -180,6 +189,7 @@ internal class SuppressionTargetInfo public SyntaxToken StartToken { get; set; } public SyntaxToken EndToken { get; set; } public SyntaxNode NodeWithTokens { get; set; } + public SyntaxNode TargetMemberNode { get; set; } } private async Task GetSuppressionTargetInfoAsync(Document document, TextSpan span, CancellationToken cancellationToken) @@ -261,7 +271,7 @@ private async Task GetSuppressionTargetInfoAsync(Document targetSymbol = semanticModel.Compilation.Assembly; } - return new SuppressionTargetInfo() { TargetSymbol = targetSymbol, NodeWithTokens = nodeWithTokens, StartToken = startToken, EndToken = endToken }; + return new SuppressionTargetInfo() { TargetSymbol = targetSymbol, NodeWithTokens = nodeWithTokens, StartToken = startToken, EndToken = endToken, TargetMemberNode = targetMemberNode }; } internal SyntaxNode GetNodeWithTokens(SyntaxToken startToken, SyntaxToken endToken, SyntaxNode root) diff --git a/src/Features/Core/Portable/FeaturesResources.Designer.cs b/src/Features/Core/Portable/FeaturesResources.Designer.cs index 2d200058e33..add1d2842f0 100644 --- a/src/Features/Core/Portable/FeaturesResources.Designer.cs +++ b/src/Features/Core/Portable/FeaturesResources.Designer.cs @@ -1863,6 +1863,15 @@ internal class FeaturesResources { } } + /// + /// Looks up a localized string similar to in Source (attribute). + /// + internal static string in_Source_attribute { + get { + return ResourceManager.GetString("in_Source_attribute", resourceCulture); + } + } + /// /// Looks up a localized string similar to in Suppression File. /// diff --git a/src/Features/Core/Portable/FeaturesResources.resx b/src/Features/Core/Portable/FeaturesResources.resx index 279054205c7..f9d2c48cc76 100644 --- a/src/Features/Core/Portable/FeaturesResources.resx +++ b/src/Features/Core/Portable/FeaturesResources.resx @@ -1617,4 +1617,7 @@ This version used in: {2} Target type matches + + in Source (attribute) + \ No newline at end of file diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf index f27ed46b80a..f5ad300b16c 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.cs.xlf @@ -497,6 +497,11 @@ obecná přetížení + + in Source (attribute) + in Source (attribute) + + overload přetížení diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf index 5faf06770bf..988dc8ba8b0 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.de.xlf @@ -497,6 +497,11 @@ generische Überladungen + + in Source (attribute) + in Source (attribute) + + overload Überladung diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf index 5abccd94bef..4c397d70849 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.es.xlf @@ -497,6 +497,11 @@ sobrecargas genéricas + + in Source (attribute) + in Source (attribute) + + overload sobrecarga diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf index 245412b89b0..49f468ccfed 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.fr.xlf @@ -497,6 +497,11 @@ surcharges génériques + + in Source (attribute) + in Source (attribute) + + overload surcharge diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf index 7a2a34a41dd..cf73ffb37ce 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.it.xlf @@ -497,6 +497,11 @@ overload generici + + in Source (attribute) + in Source (attribute) + + overload overload diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf index 95ed611c082..c0ffb590555 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ja.xlf @@ -497,6 +497,11 @@ ジェネリック オーバーロード + + in Source (attribute) + in Source (attribute) + + overload オーバーロード diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf index 0a443ceb482..c01278baf44 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ko.xlf @@ -497,6 +497,11 @@ 제네릭 오버로드 + + in Source (attribute) + in Source (attribute) + + overload 오버로드 diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf index afb82db0c4b..dd7deae50b8 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pl.xlf @@ -497,6 +497,11 @@ przeciążenia ogólne + + in Source (attribute) + in Source (attribute) + + overload przeciążenie diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf index 00cf9d41fe4..e7d97e16f59 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.pt-BR.xlf @@ -497,6 +497,11 @@ sobrecargas genéricas + + in Source (attribute) + in Source (attribute) + + overload sobrecarga diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf index 074d965cbfd..5a0d98be287 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.ru.xlf @@ -497,6 +497,11 @@ универсальные перегрузки + + in Source (attribute) + in Source (attribute) + + overload перегрузка diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf index 64401357268..f685a0ff983 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.tr.xlf @@ -497,6 +497,11 @@ genel aşırı yüklemeler + + in Source (attribute) + in Source (attribute) + + overload aşırı yükleme diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf index 15f2519bd60..8ceb0f9a14a 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hans.xlf @@ -497,6 +497,11 @@ 多个泛型重载 + + in Source (attribute) + in Source (attribute) + + overload 重载 diff --git a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf index 7c4d35c9d1f..f46605dd158 100644 --- a/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf +++ b/src/Features/Core/Portable/xlf/FeaturesResources.zh-Hant.xlf @@ -497,6 +497,11 @@ 泛型多載 + + in Source (attribute) + in Source (attribute) + + overload 多載 diff --git a/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb b/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb index 37180ccf3a6..896a6375b1e 100644 --- a/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb +++ b/src/Features/VisualBasic/Portable/CodeFixes/Suppression/VisualBasicSuppressionCodeFixProvider.vb @@ -122,7 +122,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Suppression Protected Overrides Function AddGlobalSuppressMessageAttribute(newRoot As SyntaxNode, targetSymbol As ISymbol, diagnostic As Diagnostic, workspace As Workspace, cancellationToken As CancellationToken) As SyntaxNode Dim compilationRoot = DirectCast(newRoot, CompilationUnitSyntax) Dim isFirst = Not compilationRoot.Attributes.Any() - Dim attributeList = CreateAttributeList(targetSymbol, diagnostic) + Dim attributeList = CreateAttributeList(targetSymbol, diagnostic, isAssemblyAttribute:=True) Dim attributeStatement = SyntaxFactory.AttributesStatement(New SyntaxList(Of AttributeListSyntax)().Add(attributeList)) If Not isFirst Then @@ -144,16 +144,24 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Suppression Return compilationRoot.AddAttributes(attributeStatement).WithLeadingTrivia(leadingTrivia) End Function - Private Function CreateAttributeList(targetSymbol As ISymbol, diagnostic As Diagnostic) As AttributeListSyntax - Dim attributeTarget = SyntaxFactory.AttributeTarget(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)) + Protected Overrides Function AddLocalSuppressMessageAttribute(targetNode As SyntaxNode, targetSymbol As ISymbol, diagnostic As Diagnostic) As SyntaxNode + Dim memberNode = DirectCast(targetNode, StatementSyntax) + Dim attributeList = CreateAttributeList(targetSymbol, diagnostic, isAssemblyAttribute:=False) + Dim leadingTrivia = memberNode.GetLeadingTrivia() + memberNode = memberNode.WithoutLeadingTrivia() + Return memberNode.AddAttributeLists(attributeList).WithLeadingTrivia(leadingTrivia) + End Function + + Private Function CreateAttributeList(targetSymbol As ISymbol, diagnostic As Diagnostic, isAssemblyAttribute As Boolean) As AttributeListSyntax + Dim attributeTarget = If(isAssemblyAttribute, SyntaxFactory.AttributeTarget(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)), Nothing) Dim attributeName = SyntaxFactory.ParseName(SuppressMessageAttributeName) - Dim attributeArguments = CreateAttributeArguments(targetSymbol, diagnostic) + Dim attributeArguments = CreateAttributeArguments(targetSymbol, diagnostic, isAssemblyAttribute) Dim attribute As AttributeSyntax = SyntaxFactory.Attribute(attributeTarget, attributeName, attributeArguments) Return SyntaxFactory.AttributeList().AddAttributes(attribute) End Function - Private Function CreateAttributeArguments(targetSymbol As ISymbol, diagnostic As Diagnostic) As ArgumentListSyntax + Private Function CreateAttributeArguments(targetSymbol As ISymbol, diagnostic As Diagnostic, isAssemblyAttribute As Boolean) As ArgumentListSyntax ' SuppressMessage("Rule Category", "Rule Id", Justification := "Justification", Scope := "Scope", Target := "Target") Dim category = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(diagnostic.Descriptor.Category)) Dim categoryArgument = SyntaxFactory.SimpleArgument(category) @@ -169,15 +177,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeFixes.Suppression Dim attributeArgumentList = SyntaxFactory.ArgumentList().AddArguments(categoryArgument, ruleIdArgument, justificationArgument) Dim scopeString = GetScopeString(targetSymbol.Kind) - If scopeString IsNot Nothing Then - Dim scopeExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(scopeString)) - Dim scopeArgument = SyntaxFactory.SimpleArgument(SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName("Scope")), expression:=scopeExpr) + If isAssemblyAttribute Then + If scopeString IsNot Nothing Then + Dim scopeExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(scopeString)) + Dim scopeArgument = SyntaxFactory.SimpleArgument(SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName("Scope")), expression:=scopeExpr) - Dim targetString = GetTargetString(targetSymbol) - Dim targetExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(targetString)) - Dim targetArgument = SyntaxFactory.SimpleArgument(SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName("Target")), expression:=targetExpr) + Dim targetString = GetTargetString(targetSymbol) + Dim targetExpr = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal(targetString)) + Dim targetArgument = SyntaxFactory.SimpleArgument(SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName("Target")), expression:=targetExpr) - attributeArgumentList = attributeArgumentList.AddArguments(scopeArgument, targetArgument) + attributeArgumentList = attributeArgumentList.AddArguments(scopeArgument, targetArgument) + End If End If Return attributeArgumentList -- GitLab