IEnumerable<AnalyzerTreeNodeData> FindReferencesInType(TypeDef type) { string name = analyzedMethod.Name; foreach (MethodDef method in type.Methods) { if (!method.HasBody) continue; Instruction foundInstr = null; foreach (Instruction instr in method.Body.Instructions) { IMethod mr = instr.Operand as IMethod; if (mr != null && !mr.IsField && mr.Name == name && Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && mr.ResolveMethodDef() == analyzedMethod) { foundInstr = instr; break; } } if (foundInstr != null) { MethodDef codeLocation = GetOriginalCodeLocation(method) as MethodDef; if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { var node = new MethodNode(codeLocation) { Context = Context }; if (codeLocation == method) node.SourceRef = new SourceRef(method, foundInstr.Offset, foundInstr.Operand as IMDTokenProvider); yield return node; } } } }
IEnumerable<IAnalyzerTreeNodeData> FindReferencesInType(TypeDef type) { IAnalyzerTreeNodeData newNode = null; try { if (!TypesHierarchyHelpers.IsBaseType(analyzedMethod.DeclaringType, type, resolveTypeArguments: false)) yield break; foreach (MethodDef method in type.Methods) { if (TypesHierarchyHelpers.IsBaseMethod(analyzedMethod, method)) { bool hidesParent = !method.IsVirtual ^ method.IsNewSlot; newNode = new MethodNode(method, hidesParent) { Context = Context }; } } } catch (ResolveException) { // ignore this type definition. maybe add a notification about such cases. } if (newNode != null) yield return newNode; }
IEnumerable<AnalyzerTreeNodeData> FindReferencesInType(TypeDef type) { // HACK: in lieu of proper flow analysis, I'm going to use a simple heuristic // If the method accesses the event's backing field, and calls invoke on a delegate // with the same signature, then it is (most likely) raise the given event. foreach (MethodDef method in type.Methods) { bool readBackingField = false; if (!method.HasBody) continue; Instruction foundInstr = null; foreach (Instruction instr in method.Body.Instructions) { Code code = instr.OpCode.Code; if (code == Code.Ldfld || code == Code.Ldflda) { IField fr = instr.Operand as IField; if (fr.ResolveFieldDef() == eventBackingField) { readBackingField = true; } } if (readBackingField && (code == Code.Callvirt || code == Code.Call)) { IMethod mr = instr.Operand as IMethod; if (mr != null && eventFiringMethod != null && mr.Name == eventFiringMethod.Name && mr.ResolveMethodDef() == eventFiringMethod) { foundInstr = instr; break; } } } if (foundInstr != null) { MethodDef codeLocation = GetOriginalCodeLocation(method) as MethodDef; if (codeLocation != null && !HasAlreadyBeenFound(codeLocation)) { var node = new MethodNode(codeLocation) { Context = Context }; if (codeLocation == method) node.SourceRef = new SourceRef(method, foundInstr.Offset, foundInstr.Operand as IMDTokenProvider); yield return node; } } } }
IEnumerable <AnalyzerTreeNodeData> FindReferencesInType(TypeDef type) { string name = analyzedMethod.Name; foreach (MethodDef method in type.Methods) { if (!method.HasBody) { continue; } Instruction?foundInstr = null; foreach (Instruction instr in method.Body.Instructions) { if (instr.Operand is IMethod mr && !mr.IsField && mr.Name == name) { // explicit call to the requested method if ((instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt) && Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && CheckEquals(mr.ResolveMethodDef(), analyzedMethod)) { foundInstr = instr; break; } // virtual call to base method if (instr.OpCode.Code == Code.Callvirt) { MethodDef md = mr.ResolveMethodDef(); if (md is null) { // cannot resolve the operand, so ignore this method break; } if (CheckEquals(md, baseMethod)) { foundInstr = instr; break; } } } } if (!(foundInstr is null)) { if (GetOriginalCodeLocation(method) is MethodDef codeLocation && !HasAlreadyBeenFound(codeLocation)) { var node = new MethodNode(codeLocation) { Context = Context }; if (codeLocation == method) { node.SourceRef = new SourceRef(method, foundInstr.Offset, foundInstr.Operand as IMDTokenProvider); } yield return(node); } } } if (!(property is null)) { foreach (var node in FieldAccessNode.CheckCustomAttributeNamedArgumentWrite(Context, type, property)) { if (node is MethodNode methodNode && methodNode.Member is MethodDef method && HasAlreadyBeenFound(method)) { continue; } yield return(node); } } }
IEnumerable <AnalyzerTreeNodeData> FindReferencesInType(TypeDef type) { string name = analyzedMethod.Name; foreach (MethodDef method in type.Methods) { if (!method.HasBody) { continue; } Instruction?foundInstr = null; if (implMapName is not null) { foreach (var instr in method.Body.Instructions) { if (instr.Operand is IMethod mr && !mr.IsField && mr.ResolveMethodDef() is MethodDef md && // DllImport methods are the same if module + func name are identical md?.ImplMap is ImplMap otherImplMap && implMapName == GetDllImportMethodName(md, otherImplMap) && StringComparer.OrdinalIgnoreCase.Equals(implMapModule, NormalizeModuleName(otherImplMap.Module?.Name))) { foundInstr = instr; break; } } } else { foreach (var instr in method.Body.Instructions) { if (instr.Operand is IMethod mr && !mr.IsField && mr.Name == name && Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) && CheckEquals(mr.ResolveMethodDef(), analyzedMethod)) { foundInstr = instr; break; } } } if (foundInstr is not null) { if (GetOriginalCodeLocation(method) is MethodDef codeLocation && !HasAlreadyBeenFound(codeLocation)) { var node = new MethodNode(codeLocation) { Context = Context }; if (codeLocation == method) { node.SourceRef = new SourceRef(method, foundInstr.Offset, foundInstr.Operand as IMDTokenProvider); } yield return(node); } } } if (property is not null) { foreach (var node in FieldAccessNode.CheckCustomAttributeNamedArgumentWrite(Context, type, property)) { if (node is MethodNode methodNode && methodNode.Member is MethodDef method && HasAlreadyBeenFound(method)) { continue; } yield return(node); } } }