Пример #1
0
        /// <summary>
        /// The list of paths from this method to the given called target method.
        /// </summary>
        public List <List <ModelMethod> > PathsTo(ModelMethod targetMethod)
        {
            List <List <ModelMethod> > paths = new List <List <ModelMethod> >();

            paths.Add(new List <ModelMethod>()
            {
                this
            });
            return(BuildPathsTo(paths, targetMethod));
        }
Пример #2
0
 private void BuildAllCalledByMethods(HashSet <ModelMethod> calls, ModelMethod parent)
 {
     foreach (ModelMethod m in parent.CalledByMethods)
     {
         if (!calls.Contains(m))
         {
             calls.Add(m);
             this.BuildAllCalledByMethods(calls, m);
         }
     }
 }
Пример #3
0
        /// <summary>
        /// Compares whether two ModelMethod objects reference the same CLR method.
        /// </summary>
        public override bool Equals(object obj)
        {
            ModelMethod other = obj as ModelMethod;

            if (Object.ReferenceEquals(other, null))
            {
                return(false);
            }
            else
            {
                return(this.MethodBase.Equals(other.MethodBase));
            }
        }
Пример #4
0
        /// <summary>
        /// Returns the interface methods this method implements.
        /// </summary>
        public IEnumerable <MethodInfo> GetImplementedInterfaceMethods(ModelMethod byMethod)
        {
            if ((this.interfaceMapping == null) && (byMethod.DeclaringType.IsInterface == false))
            {
                lock (this)
                {
                    if (this.interfaceMapping == null)
                    {
                        this.interfaceMapping = new Dictionary <MethodBase, List <MethodInfo> >();

                        foreach (Type itype in this.runtimeType.GetInterfaces())
                        {
                            InterfaceMapping map = this.runtimeType.GetInterfaceMap(itype);
                            for (int i = 0; i < map.InterfaceMethods.Length; i++)
                            {
                                List <MethodInfo> list;
                                if (!this.interfaceMapping.TryGetValue(map.TargetMethods[i], out list))
                                {
                                    list = this.interfaceMapping[map.TargetMethods[i]] = new List <MethodInfo>();
                                }
                                list.Add(map.InterfaceMethods[i]);
                            }
                        }
                    }
                }
            }

            List <MethodInfo> result;

            if (byMethod.DeclaringType.IsInterface)
            {
                return(EmptyMethodInfoSet);
            }
            else if (this.interfaceMapping.TryGetValue(byMethod.MethodBase, out result))
            {
                return(result);
            }
            else
            {
                return(EmptyMethodInfoSet);
            }
        }
        /// <summary>
        /// Process the given session and return a codemodel containing
        /// the in-memory method call network.
        /// </summary>
        public CodeModel Process(StaticCodeAnalyzerSession session)
        {
            List <ModelAssembly>             massemblies = new List <ModelAssembly>();
            List <ModelType>                 mtypes      = new List <ModelType>();
            Dictionary <string, ModelMethod> mmethods    = new Dictionary <string, ModelMethod>();
            ILanguageInfo   languageInfo   = session.LanguageInfo;
            IAnalyzerFilter analyzerFilter = session.AnalyzerFilter;

            // Retrieve all methods and constructors:
            foreach (Assembly asm in session.Assemblies)
            {
                try
                {
                    if ((analyzerFilter != null) &&
                        (!analyzerFilter.ProcessAssembly(asm)))
                    {
                        continue;
                    }

                    ModelAssembly masm = new ModelAssembly(asm, languageInfo);
                    massemblies.Add(masm);

                    foreach (Type type in asm.GetTypes())
                    {
                        try
                        {
                            if ((analyzerFilter != null) &&
                                (!analyzerFilter.ProcessType(type)))
                            {
                                continue;
                            }

                            ModelType mtype = new ModelType(masm, type, languageInfo);
                            mtypes.Add(mtype);

                            foreach (MethodBase mb in type.GetConstructors(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic))
                            {
                                if ((analyzerFilter != null) &&
                                    (!analyzerFilter.ProcessMethod(mb)))
                                {
                                    continue;
                                }

                                mmethods[GetMethodKey(mb)] = new ModelMethod(mtype, mb, languageInfo);
                            }
                            foreach (MethodBase mb in type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly))
                            {
                                if ((analyzerFilter != null) &&
                                    (!analyzerFilter.ProcessMethod(mb)))
                                {
                                    continue;
                                }

                                mmethods[GetMethodKey(mb)] = new ModelMethod(mtype, mb, languageInfo);
                            }
                        }
                        catch (Exception ex)
                        {
                            // Rethrow with mode info:
                            throw new TargetInvocationException(
                                      String.Format("Error reading type {0}: {1} (See innerException.)", type.FullName, ex.Message),
                                      ex
                                      );
                        }
                    }
                }
                catch (ReflectionTypeLoadException ex)
                {
                    // Rethrow with mode info:
                    throw new TargetInvocationException(
                              String.Format("Error reading assembly {0}: {1} (See innerException.)", asm.FullName, ex.Message),
                              ex.LoaderExceptions.FirstOrDefault() ?? ex
                              );
                }
                catch (Exception ex)
                {
                    // Rethrow with mode info:
                    throw new TargetInvocationException(
                              String.Format("Error reading assembly {0}: {1} (See innerException.)", asm.FullName, ex.Message),
                              ex
                              );
                }
            }

            // Build network of method calls:
            foreach (ModelMethod m in mmethods.Values)
            {
                try
                {
                    MethodBodyReader reader = new MethodBodyReader(m.MethodBase);

                    foreach (MethodBase calledmb in reader.GetCalledMethods(true, true))
                    {
                        ModelMethod calledm = FindMethod(mmethods, calledmb);
                        if (calledm != null)
                        {
                            m.CallsMethods.Add(calledm);
                        }
                    }
                }
                catch (InvalidOperationException ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }

            // Construct a code model:
            CodeModel codeModel = new CodeModel(
                massemblies,
                mtypes,
                mmethods.Values);

            // Apply processors:
            foreach (IProcessor processor in session.Processors)
            {
                processor.Process(codeModel);
            }

            // Construct & return a code model:
            return(codeModel);
        }
Пример #6
0
        private List <List <ModelMethod> > BuildPathsTo(List <List <ModelMethod> > paths, ModelMethod targetMethod)
        {
            List <List <ModelMethod> > newPaths = new List <List <ModelMethod> >();

            foreach (var path in paths)
            {
                if (path.Last().Equals(targetMethod))
                {
                    newPaths.Add(path);
                }
                else
                {
                    foreach (var callsMethod in path.Last().CallsMethods)
                    {
                        // Skip recursive calls:
                        if (path.Contains(callsMethod))
                        {
                            continue;
                        }

                        if (callsMethod.Equals(targetMethod))
                        {
                            List <ModelMethod> newPath = new List <ModelMethod>(path);
                            newPath.Add(callsMethod);
                            newPaths.Add(newPath);
                        }
                        else if (callsMethod.GetAllCallsMethods().Contains(targetMethod))
                        {
                            List <ModelMethod> newPath = new List <ModelMethod>(path);
                            newPath.Add(callsMethod);

                            newPaths.AddRange(BuildPathsTo(new List <List <ModelMethod> >()
                            {
                                newPath
                            }, targetMethod));
                        }
                    }
                }
            }

            return(newPaths);
        }