protected override IEnumerable <AnalyzerTreeNodeData> FetchChildren(CancellationToken ct)
        {
            InitializeAnalyzer();

            if (isSetter)
            {
                property = analyzedMethod.DeclaringType.Properties.FirstOrDefault(a => a.SetMethod == analyzedMethod);
            }

            var includeAllModules = !(property is null) && CustomAttributesUtils.IsPseudoCustomAttributeType(analyzedMethod.DeclaringType);

            ComUtils.GetMemberInfo(analyzedMethod, out isComType, out comGuid, out vtblIndex);
            includeAllModules |= isComType;
            var options = ScopedWhereUsedAnalyzerOptions.None;

            if (includeAllModules)
            {
                options |= ScopedWhereUsedAnalyzerOptions.IncludeAllModules;
            }
            if (isComType)
            {
                options |= ScopedWhereUsedAnalyzerOptions.ForcePublic;
            }
            var analyzer = new ScopedWhereUsedAnalyzer <AnalyzerTreeNodeData>(Context.DocumentService, analyzedMethod, FindReferencesInType, options);

            foreach (var child in analyzer.PerformAnalysis(ct))
            {
                yield return(child);
            }

            if (!(property is null))
            {
                var hash = new HashSet <AssemblyDef>();
                foreach (var module in analyzer.AllModules)
                {
                    if (module.Assembly is AssemblyDef asm && hash.Add(module.Assembly))
                    {
                        foreach (var node in FieldAccessNode.CheckCustomAttributeNamedArgumentWrite(Context, asm, property))
                        {
                            yield return(node);
                        }
                    }
                    foreach (var node in FieldAccessNode.CheckCustomAttributeNamedArgumentWrite(Context, module, property))
                    {
                        yield return(node);
                    }
                }
            }

            ReleaseAnalyzer();
        }
Exemple #2
0
        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 &&
                        Helpers.IsReferencedBy(analyzedMethod.DeclaringType, mr.DeclaringType) &&
                        CheckEquals(mr.ResolveMethodDef(), analyzedMethod))
                    {
                        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);
                }
            }
        }
Exemple #3
0
        protected override IEnumerable <AnalyzerTreeNodeData> FetchChildren(CancellationToken ct)
        {
            foundMethods = new ConcurrentDictionary <MethodDef, int>();

            if (isSetter)
            {
                property = analyzedMethod.DeclaringType.Properties.FirstOrDefault(a => a.SetMethod == analyzedMethod);
            }

            var includeAllModules = (property is not null && CustomAttributesUtils.IsPseudoCustomAttributeType(analyzedMethod.DeclaringType)) || implMapName is not null;
            var options           = ScopedWhereUsedAnalyzerOptions.None;

            if (includeAllModules)
            {
                options |= ScopedWhereUsedAnalyzerOptions.IncludeAllModules;
            }
            if (implMapName is not null)
            {
                options |= ScopedWhereUsedAnalyzerOptions.ForcePublic;
            }
            var analyzer = new ScopedWhereUsedAnalyzer <AnalyzerTreeNodeData>(Context.DocumentService, analyzedMethod, FindReferencesInType, options);

            foreach (var child in analyzer.PerformAnalysis(ct))
            {
                yield return(child);
            }

            if (property is not null)
            {
                var hash = new HashSet <AssemblyDef>();
                foreach (var module in analyzer.AllModules)
                {
                    if (module.Assembly is AssemblyDef asm && hash.Add(asm))
                    {
                        foreach (var node in FieldAccessNode.CheckCustomAttributeNamedArgumentWrite(Context, asm, property))
                        {
                            yield return(node);
                        }
                    }
                    foreach (var node in FieldAccessNode.CheckCustomAttributeNamedArgumentWrite(Context, module, property))
                    {
                        yield return(node);
                    }
                }
            }

            foundMethods = null;
        }
Exemple #4
0
        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);
                }
            }
        }
        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)
                    {
                        continue;
                    }
                    MethodDef?md = null;

                    if (isComType)
                    {
                        if (instr.OpCode.Code == Code.Call || instr.OpCode.Code == Code.Callvirt)
                        {
                            md ??= mr.ResolveMethodDef();
                            if (!(md is null))
                            {
                                ComUtils.GetMemberInfo(md, out bool otherIsComType, out var otherComGuid, out int otherVtblIndex);
                                if (otherIsComType && comGuid == otherComGuid && vtblIndex == otherVtblIndex)
                                {
                                    foundInstr = instr;
                                    break;
                                }
                            }
                        }
                    }

                    if (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(md ??= mr.ResolveMethodDef(), analyzedMethod))
                        {
                            foundInstr = instr;
                            break;
                        }
                        // virtual call to base method
                        if (instr.OpCode.Code == Code.Callvirt)
                        {
                            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);
                }
            }
        }