2

I have created an FxCop rule that checks for DateTime.Now use. It works pretty well, except that it reports the offending line number as the start of the method, rather than the line of code that actually calls DateTime.Now. What do I need to do to get the right line number in the FxCop report. Here's my code:

public override void VisitMemberBinding(MemberBinding memberBinding)
{
   string name = memberBinding.BoundMember.FullName;
   if (name == "System.DateTime.get_Now")
   {
      Problems.Add(new Problem(GetResolution(), memberBinding.BoundMember.SourceContext));
   }

   base.VisitMemberBinding(memberBinding);
}

I've tried memberBinding.SourceContext and memberBinding.BoundMember.SourceContext and both return the method's start line number.

I could use SourceContext.(Start|End)LineNumber but which one? Seems that I am just not using the correct object.SourceContext

Cœur
  • 37,241
  • 25
  • 195
  • 267
slolife
  • 19,520
  • 20
  • 78
  • 121

1 Answers1

2

The core problem is that the FxCop analysis engine does not assign a source context to a member binding. It does, however, assign a source context to a method call, so you could replace your VisitMemberBinding override with the following VisitMethodCall override:

public override void VisitMethodCall(MethodCall call)
{
    string name = ((MemberBinding)call.Callee).BoundMember.FullName;
    if (name == "System.DateTime.get_Now")
    {
        this.Problems.Add(new Problem(this.GetResolution(), call));
    }

    base.VisitMethodCall(call);
}
Nicole Calinoiu
  • 20,843
  • 2
  • 44
  • 49
  • Worked great, thanks! So VisitMemeberBinding occurs inside of the DateTime.Now property and VisitMethodCall happens when DateTime.Now is being called? Or the other way around? – slolife Oct 28 '11 at 18:19
  • 1
    VisitMemberBinding will actually be called by the base VisitMethodCall. However, the method call has extra metadata available since it is an instruction whose source context is tracked in the PDB file. I'm not quite sure why the FxCop team didn't choose to transfer that source context to the member binding for the called method since I can't think of any case where it wouldn't be reliable. Either way, it's not there, so we can't use it. – Nicole Calinoiu Oct 28 '11 at 19:10