I followed the steps here to create a new custom rule and add it to the ruleset in VSStudio 2013:
http://blog.tatham.oddie.com.au/2010/01/06/custom-code-analysis-rules-in-vs2010-and-how-to-make-them-run-in-fxcop-and-vs2008-too/
However, despite all my efforts, the custom rule does not show up in the ruleset file.
If I add the rule in the FXCop Editor, it shows up and analyzes the target project correctly.
This is the Rule File, which is an embedded resource in the project:
<?xml version="1.0" encoding="utf-8" ?>
<Rules FriendlyName="PSI Custom FxCop Rules">
<Rule TypeName="EnforceHungarianNotation" Category="PSIRules" CheckId="CR0001">
<Name>Enforce Hungarian Notation</Name>
<Description>Checks fields for compliance with Hungarian notation.</Description>
<Resolution>Field {0} is not in Hungarian notation. Field name should be prefixed with '{1}'.</Resolution>
<MessageLevel Certainty="100">Error</MessageLevel>
<FixCategories>Breaking</FixCategories>
<Url />
<Owner />
<Email />
</Rule>
</Rules>
This is my RuleSet:
<?xml version="1.0" encoding="utf-8"?>
<RuleSet Name="New Rule Set" Description=" " ToolsVersion="10.0">
<RuleHintPaths>
<Path>C:\App\PSI\Development\Source\JHA.ProfitStars.PSI\JHA.ProfitStars
.PSI.FxCop\bin\Debug</Path>
</RuleHintPaths>
</RuleSet>
I even tried adding the line below, but now it shows an Unknown rule in the ruleset:
<Rules AnalyzerId="Microsoft.Analyzers.ManagedCodeAnalysis"
RuleNamespace="Microsoft.Rules.Managed">
<Rule Id="CR0001" Action="Error" />
</Rules>
Could someone please help me understand what I am doing wrong here?
Edited:
BaseClass for rules:
internal abstract class BaseFxCopRule : BaseIntrospectionRule
{
protected BaseFxCopRule(string ruleName)
: base(ruleName, "JHA.ProfitStars.PSI.FxCop.Rules", typeof(BaseFxCopRule).Assembly)
{ }
}
Rules Class:
internal sealed class EnforceHungarianNotation : BaseFxCopRule
{
public EnforceHungarianNotation()
: base("EnforceHungarianNotation")
{
}
public override TargetVisibilities TargetVisibility
{
get
{
return TargetVisibilities.NotExternallyVisible;
}
}
public override ProblemCollection Check(Member member)
{
Field field = member as Field;
if (field == null)
{
// This rule only applies to fields.
// Return a null ProblemCollection so no violations are reported for this member.
return null;
}
if (field.IsStatic)
{
CheckFieldName(field, s_staticFieldPrefix);
}
else
{
CheckFieldName(field, s_nonStaticFieldPrefix);
}
// By default the Problems collection is empty so no violations will be reported
// unless CheckFieldName found and added a problem.
return Problems;
}
private const string s_staticFieldPrefix = "s_";
private const string s_nonStaticFieldPrefix = "m_";
private void CheckFieldName(Field field, string expectedPrefix)
{
if (!field.Name.Name.StartsWith(expectedPrefix, StringComparison.Ordinal))
{
Resolution resolution = GetResolution(
field, // Field {0} is not in Hungarian notation.
expectedPrefix // Field name should be prefixed with {1}.
);
Problem problem = new Problem(resolution);
Problems.Add(problem);
}
}
}