Ejemplo n.º 1
0
        /// <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;
        }