2011-06-21 11 views
5

द्वारा बुलाए गए तरीकों पर लागू होता है, मैं एक FxRule बनाना चाहता हूं जो एक विधि लागू करता है, केवल तभी जब विधि किसी विशिष्ट वर्ग से कॉल की जाती है।FxCop में कस्टम नियम केवल विशेष प्रकार की विधि

नोट: मैं सिर्फ एक विशेष वर्ग की विधि पर एक नियम लागू नहीं करना चाहता हूं, मैं अन्य तरीकों को बुलाकर विधियों को संभालने में सक्षम होना चाहता हूं जो मुक्केबाजी करते हैं।

मैं बॉक्सिंग करने वाली विधि से जुड़ी समस्याओं की रिपोर्ट करने के लिए FxCop प्राप्त करना चाहता हूं। ,

using System; 
using System.Linq; 
using Microsoft.FxCop.Sdk; 
using System.Collections.Generic; 

class CheckUpdatableComponents : BaseIntrospectionRule 
{ 
    private string[] MethodsToCheck = new string[] { "BeginDraw", "BeginRun", "Draw", "EndRun", "EndDraw", "Update" }; 

    /// <summary>Gets the base class hooked up.</summary> 
    public CheckUpdatableComponents() 
     : base("CheckUpdatableComponents", "FxCopRules.Rules", typeof(CheckUpdatableComponents).Assembly) 
    { 
    } 

    public override ProblemCollection Check(string namespaceName, TypeNodeCollection types) 
    { 
     foreach (var type in types.Where(T => IsSubClassOf(T, "Microsoft.Xna.Framework.Game"))) 
     { 
      foreach (var MethodToCheck in MethodsToCheck) 
      { 
       Method RunMethod = type.GetMethod(Identifier.For(MethodToCheck)); 

       if (RunMethod != null) 
       { 
        Visit(RunMethod); 
       } 
      } 
     } 

     return Problems; 
    } 

    public override void VisitMethod(Method method) 
    { 
       Problems.Add(new Problem(GetResolution(), method, method.ToString())); // This problem only appears for each of the RunMethods, and doesn't seem to be recursing down the tree. 


     foreach (var Instruction in method.Instructions) 
     { 
      if (Instruction.NodeType == NodeType.Box || 
       Instruction.NodeType == NodeType.Unbox || 
       Instruction.NodeType == NodeType.UnboxAny || 
       Instruction.OpCode == OpCode.Box || 
       Instruction.OpCode == OpCode.Unbox || 
       Instruction.OpCode == OpCode.Unbox_Any) 
      { 
      } 
     } 

     base.VisitMethod(method); 
    } 

    private bool IsSubClassOf(TypeNode type, string typeName) 
    { 
     if (type.FullName == typeName) 
      return true; 
     if (type.BaseType == null) 
      return false; 
     else 
      return IsSubClassOf(type.BaseType, typeName); 
    } 
} 

ऊपर कोड के साथ मेरा मुद्दा सबसे पहले है कि यह recursing जा करने के लिए प्रकट नहीं होता है:

नीचे कोड मैं अब तक है। दूसरा, यह है कि FxCop नामस्थान से जुड़े समस्याओं की रिपोर्ट करता है (संभवतः क्योंकि मैं चेक (नेमस्पेस ....) भाग का उपयोग करके विज़िट को लात मारता हूं।

मेरी समस्या यह है कि मैं चाहता हूं कि FxCop एक विधि की रिपोर्ट करे एक समस्या के रूप में मुक्केबाजी, लेकिन केवल अगर इसे किसी विशेष विधि से बुलाया जाता है, हालांकि मेरे पास कॉल पेड़ को चलाने का कोई तरीका नहीं है, तो मैं अपने शुरुआती स्थान के साथ समस्याओं की जांच के लिए केवल निम्न नोड्स पर जा सकता हूं।

क्या कोई भी किया है बात इस तरह की पहले?

मैं यह कैसे पता लगा सकते हैं कि क्या तरीकों कॉल किसी दिए गए विधि?

उत्तर

4

संपादित करें: यह वर्चुअल विधि कॉल के मामले में काम नहीं करता है जहां आईएल callvirt है। मेरा प्रश्न here देखें।

मैं CallGraph.CallersFor() विधि को खोजकर इसे काम करने में कामयाब रहा। अब मैं किसी दिए गए गुण के साथ घोषित विधियों की तलाश कर रहा हूं, या किसी दिए गए गुण वाले वर्ग द्वारा घोषित किया गया है, लेकिन प्रिंसिपल वही है।

using System; 
using System.Linq; 
using Microsoft.FxCop.Sdk; 
using System.Collections.Generic; 

class CheckUpdatableComponents : BaseIntrospectionRule 
{ 
    // private string[] MethodsToCheckNames = new string[] { "BeginDraw", "BeginRun", "Draw", "EndRun", "EndDraw", "Update" }; 

    /// <summary>Gets the base class hooked up.</summary> 
    public CheckUpdatableComponents() 
     : base("CheckUpdatableComponents", "FxCopRules.Rules", typeof(CheckUpdatableComponents).Assembly) 
    { 
    } 

    public override ProblemCollection Check(Member member) 
    { 

     Method method = member as Method; 

     if (method != null) 
     { 
      if (ShouldCheckMethod(method)) 
      { 
       foreach (var Instruction in method.Instructions) 
       { 
        if (Instruction.NodeType == NodeType.Box || 
         Instruction.NodeType == NodeType.Unbox || 
         Instruction.NodeType == NodeType.UnboxAny || 
         Instruction.OpCode == OpCode.Box || 
         Instruction.OpCode == OpCode.Unbox || 
         Instruction.OpCode == OpCode.Unbox_Any) 
        { 
         Problems.Add(new Problem(GetResolution(), Instruction, Instruction.SourceContext.StartLine.ToString())); 
        } 
       } 
      } 
     } 

     return Problems; 
    } 

    public bool ShouldCheckMethod(Method method) 
    { 
     Queue<Method> MethodsToCheck = new Queue<Method>(); 

     List<Method> MethodsChecked = new List<Method>(); 

     MethodsToCheck.Enqueue(method); 

     while (MethodsToCheck.Count != 0) 
     { 
      Method MethodToCheck = MethodsToCheck.Dequeue(); 

      if (!MethodsChecked.Contains(MethodToCheck) && MethodToCheck != null) 
      { 
       /*if (IsSubClassOf(MethodToCheck.DeclaringType, "Microsoft.Xna.Framework.Game") && 
        MethodsToCheckNames.Contains(MethodToCheck.Name.Name)) 
       { 
        return true; 
       }*/ 

       foreach (var attribute in MethodToCheck.Attributes.Union(MethodToCheck.DeclaringType.Attributes)) 
       { 
        if (attribute.Type != null && 
         attribute.Type.FullName == "GridEngine.Components.Debugging.Attributes.FxCop.PerformanceCriticalAttribute") 
        { 
         return true; 
        } 
       } 

       // Add methods up the class tree 
       MethodsToCheck.Enqueue(MethodToCheck.OverriddenMethod); 
       MethodsToCheck.Enqueue(MethodToCheck.HiddenMethod); 



       // Add calling methods 
       foreach (var CallingMethod in CallGraph.CallersFor(MethodToCheck)) 
       { 
        MethodsToCheck.Enqueue(CallingMethod); 
       } 
      } 

      MethodsChecked.Add(MethodToCheck); 
     } 

     return false; 
    } 

    private bool IsSubClassOf(TypeNode type, string typeName) 
    { 
     if (type.FullName == typeName) 
      return true; 
     if (type.BaseType == null) 
      return false; 
     else 
      return IsSubClassOf(type.BaseType, typeName); 
    } 
} 
संबंधित मुद्दे