FxCop中的自定义规则仅适用于特定类型方法调用的方法

我想创建一个应用方法的FxRule,只有在从特定类调用该方法时才会这样做。

注意:我不想只是将规则应用于特定类的方法,我希望能够处理调用其他方法调用其他方法进行装箱的方法。

我想让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" }; /// Gets the base class hooked up. 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); } } 

我对上述代码的问题首先是它似乎没有递归。 其次,FxCop将问题报告为与命名空间相关联(可能是因为我使用Check(名称空间….)部分启动了访问。

我的问题是我希望FxCop报告一个有拳击作为问题的方法,但只有当它被特定方法调用时,但是我无法走上调用树,我只能访问较低的节点来检查我的起始位置问题。

有没有人以前做过这种事情?

我怎样才能找出调用给定方法的方法?

编辑:这在IL是callvirt的虚方法调用的情况下callvirt 。 在这里看到我的问题。

我设法通过发现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" }; /// Gets the base class hooked up. 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 MethodsToCheck = new Queue(); List MethodsChecked = new List(); 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); } }