When SuppressMessageAttribute is used in code
to override an FxCop rule, the programmer may
optionally specify the Justification property to
explain the reason for using the attribute. This is a good practice which
the following rule will help enforce.
The implementation requires numerous Check
methods to be overridden because the attribute
SuppressMessageAttribute can be placed on various
kinds of targets in the source code.
Rule XML:
<Rule TypeName="SpecifySuppressMessageJustification" Category="Tutorial" CheckId="TT1035"> <Name>Specify SuppressMessage justification</Name> <Description> The SuppressMessage.Justification property should be set to an explanation of why you are suppressing an FxCop rule. </Description> <Url></Url> <Resolution>Specify the Justification property.</Resolution> <MessageLevel Certainty="95">Warning</MessageLevel> <Email></Email> <FixCategories>NonBreaking</FixCategories> <Owner></Owner> </Rule>
Rule Implementation:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.FxCop.Sdk;
namespace TutorialRules
{
class SpecifySuppressMessageJustification : BaseIntrospectionRule
{
public SpecifySuppressMessageJustification()
:
base("SpecifySuppressMessageJustification", "TutorialRules.TutorialRules",
typeof(SpecifySuppressMessageJustification).Assembly)
{
}
public override ProblemCollection Check(ModuleNode module)
{
AssemblyNode assmbly = module as AssemblyNode;
if (assmbly != null)
{
CheckSuppressMessage(assmbly.ModuleAttributes);
}
CheckSuppressMessage(module.Attributes);
return this.Problems;
}
public override ProblemCollection Check(TypeNode type)
{
CheckSuppressMessage(type.Attributes);
return this.Problems;
}
public override ProblemCollection Check(Member member)
{
Method methd = member as Method;
if (methd != null && methd.ReturnAttributes != null)
{
CheckSuppressMessage(methd.ReturnAttributes);
}
CheckSuppressMessage(member.Attributes);
return this.Problems;
}
public override ProblemCollection Check(Parameter parameter)
{
CheckSuppressMessage(parameter.Attributes);
return this.Problems;
}
public void CheckSuppressMessage(AttributeNodeCollection attributes)
{
foreach (AttributeNode attr in attributes)
{
if (attr.Type == FrameworkTypes.SuppressMessageAttribute)
{
Literal lit = attr.GetNamedArgument(Identifier.For("Justification")) as Literal;
if (lit == null || string.IsNullOrEmpty((string)lit.Value))
{
this.Problems.Add(new Problem(this.GetResolution()));
}
}
}
}
}
}