Bug in FxCop 1.32 displaying an FxCop custom rule error
When I run FxCop.exe (build 50628.0) and analyze an assembly using my custom rules and then double click on the error generated from my custom rules I get the following error:-
System.NullReferenceException: Object reference not set to an instance of an object.
at Microsoft.FxCop.UI.MessageDetailsForm.DisplayMessage()
at Microsoft.FxCop.UI.MessageDetailsForm.SetListViewItem(ListViewItem value)
at Microsoft.FxCop.UI.MessageListView.UpdateSelections()
at Microsoft.FxCop.UI.MessageListView.MouseUpHandler(Object sender, MouseEventArgs e)
My rule's XML is:-
<Rule TypeName="ThreadNotProvidedByFactory" Category="Threads" CheckId="C0001">
<Name>Thread not provided by ThreadFactory</Name>
<Description>A Thread has been constructed using a Thread constructor instead of ThreadFactory.CreateThread</Description>
<Owner>Guy Smith-Ferrier</Owner>
<Url>www.notdefined.com</Url>
<Resolution>Construct new Thread objects using ThreadFactory.CreateThread</Resolution>
<Email>gsf@notdefined.com</Email>
<MessageLevel Certainty="99">Warning</MessageLevel>
<FixCategories>Breaking</FixCategories>
</Rule>
This looks like a bug in FxCop to me. It could be caused by a bad rule definition but if it is then FxCop needs to check for the bad rule when loading the rule assembly.
Guy
Yes, you've certainly uncovered a negative code path FxCop is not handling correctly. This path is provoked by an issue in your custom rule we'll want to chase down, however. Can you post the code your rule uses to create and return violations (that is, Problem instances)?
Michael
Michael,
Here's the code (not sure how much you wanted so I have pasted the lot).
Guy
public class ThreadNotProvidedByFactory: BaseIntrospectionRule
{
private bool classUsed;
public ThreadNotProvidedByFactory()
: base("ThreadNotProvidedByFactory", "CompanyRules.RuleData", typeof(ThreadNotProvidedByFactory).Assembly)
{
}
public override ProblemCollection Check(Member member)
{
Method method = member as Method;
if (method != null)
{
classUsed = false;
VisitMethod(method);
if (classUsed)
{
Resolution resolution = GetResolution(
new string[] {method.Name.Name});
Problems.Add(new Problem(resolution));
return Problems;
}
}
return base.Check (member);
}
public override Expression VisitConstruct(Construct cons)
{
if (cons != null)
{
MemberBinding memberBinding = cons.Constructor as MemberBinding;
if (memberBinding != null)
{
InstanceInitializer instanceInitializer =
memberBinding.BoundMember as InstanceInitializer;
if (instanceInitializer != null &&
instanceInitializer.DeclaringType.FullName ==
"System.Threading.Thread")
classUsed = true;
}
}
return base.VisitConstruct (cons);
}
}