Example #1
0
        /// <summary>
        /// Analyzes the referenced assemblies.
        /// </summary>
        /// <param name="analyzer">The analyzer.</param>
        /// <param name="refAssemblies">The referenced assemblies.</param>
        /// <param name="assemblies">The list to put the information about the analyzed assemblies in.</param>
        private void AnalyzeReferencedAssemblies(IILAnalyzer analyzer, List <ITaskItem> refAssemblies, List <AssemblyElement> assemblies)
        {
            // Only if we have unresolved types
            if (analyzer.UnresolvedTypes.Count == 0)
            {
                return;
            }

            Log.LogMessageFromResources("NumberOfReferencesToResolve", analyzer.UnresolvedTypes.Count);

            // The previous step could introduce new assemblies, so add those to the list.
            List <string> assemblyFiles = new List <string>();

            assemblyFiles.AddRange(analyzer.ResolveAssemblyLocations());

            // Create analyzer new config
            CecilAnalyzerConfiguration configuration = new CecilAnalyzerConfiguration(_repositoryFileName);

            configuration.DoFieldAnalysis       = false;
            configuration.DoMethodCallAnalysis  = false;
            configuration.ExtractUnresolvedOnly = true;
            configuration.BinFolder             = _binFolder;

            // Store before reset
            IList <string> tempUnresolvedTypes = analyzer.UnresolvedTypes;

            // Create a new analyzer using the object builder
            IEntitiesAccessor entitiesAccessor = EntitiesAccessor.Instance;

            analyzer = DIHelper.CreateObject <CecilILAnalyzer>(CreateContainer(entitiesAccessor, configuration));

            // Set the unresolved types (because we have reset the analyzer)
            foreach (string type in tempUnresolvedTypes)
            {
                analyzer.UnresolvedTypes.Add(type);
            }

            // Add the assemblies to analyze.
            foreach (ITaskItem item in refAssemblies)
            {
                string filename = item.ToString();
                if (!assemblyFiles.Contains(filename))
                {
                    assemblyFiles.Add(filename);
                }
            }

            // Try to resolve all the references.
            do
            {
                // Loop through all the referenced assemblies.
                foreach (string filename in assemblyFiles)
                {
                    try
                    {
                        // See if we already have this assembly in the list
                        AssemblyConfig asmConfig = _assembliesInConfig.Find(delegate(AssemblyConfig ac)
                        {
                            return(ac.FileName.Equals(filename));
                        });

                        // If a source assembly has changed, then new unresolved types can be introduced.
                        // So we must rescan the library based on the value of assemblyChanged.
                        // TODO: can this be optimized?
                        if (!_assembliesDirty && asmConfig != null && File.Exists(asmConfig.TypeSpecificationFile))
                        {
                            // Already in the config. Check the last modification date.
                            if (asmConfig.Timestamp == File.GetLastWriteTime(filename).Ticks)
                            {
                                // Assembly has not been modified, skipping analysis
                                Log.LogMessageFromResources("AssemblyNotModified", asmConfig.Name);

                                _assembliesToStore.Add(asmConfig);
                                continue;
                            }
                        }

                        // Either we could not find the assembly in the config or it was changed.

                        Log.LogMessageFromResources("AnalyzingFile", filename);
                        Stopwatch sw = Stopwatch.StartNew();

                        IAnalyzerResults results = analyzer.ExtractAllTypes(filename);
                        ShowLogItems(results.Log.LogItems);

                        // Store the filters
                        StoreFilters(results);

                        // Create a new AssemblyConfig object
                        AssemblyElement assembly = results.Assembly;
                        if (assembly != null)
                        {
                            asmConfig = new AssemblyConfig();

                            asmConfig.FileName    = filename;
                            asmConfig.Name        = assembly.Name;
                            asmConfig.Timestamp   = File.GetLastWriteTime(filename).Ticks;
                            asmConfig.Assembly    = assembly;
                            asmConfig.IsReference = true;

                            // Generate a unique filename
                            asmConfig.GenerateTypeSpecificationFileName(_intermediateOutputPath);

                            _assembliesToStore.Add(asmConfig);
                            assemblies.Add(assembly);
                        }

                        sw.Stop();
                        Log.LogMessageFromResources("AssemblyAnalyzed", assembly.Types.Count, analyzer.UnresolvedAssemblies.Count, sw.Elapsed.TotalSeconds);
                    }
                    catch (ILAnalyzerException ex)
                    {
                        Log.LogErrorFromException(ex, true);
                    }
                    catch (ArgumentException ex)
                    {
                        Log.LogErrorFromException(ex, true);
                    }
                    catch (FileNotFoundException ex)
                    {
                        Log.LogErrorFromException(ex, true);
                    }
                    catch (BadImageFormatException ex)
                    {
                        Log.LogErrorFromException(ex, false);
                    }
                }

                // Clear the already analyzed assemblies
                assemblyFiles.Clear();

                // Get the unresolved
                assemblyFiles.AddRange(analyzer.ResolveAssemblyLocations());
            }while (analyzer.UnresolvedTypes.Count > 0 && assemblyFiles.Count > 0);
        }
Example #2
0
        private AssemblyElement AnalyzeAssembly(IILAnalyzer analyzer, ITaskItem item)
        {
            string filename = item.ToString();

            // See if we already have this assembly in the list
            AssemblyConfig asmConfig = _assembliesInConfig.Find(delegate(AssemblyConfig ac)
            {
                return(ac.FileName.Equals(filename));
            });

            if (asmConfig != null && File.Exists(asmConfig.TypeSpecificationFile))
            {
                // Already in the config. Check the last modification date.
                if (asmConfig.Timestamp == File.GetLastWriteTime(filename).Ticks)
                {
                    // Assembly has not been modified, skipping analysis
                    Log.LogMessageFromResources("AssemblyNotModified", asmConfig.Name);

                    // We still have to store this assembly, but we do not analyze it
                    _assembliesToStore.Add(asmConfig);
                    return(null);
                }
            }

            // Either we could not find the assembly in the config or it was changed.
            Log.LogMessageFromResources("AnalyzingFile", filename);
            Stopwatch sw = Stopwatch.StartNew();

            IAnalyzerResults results = analyzer.ExtractAllTypes(filename);

            ShowLogItems(results.Log.LogItems);

            // Store the filters
            StoreFilters(results);

            // Get the assembly from the results.
            AssemblyElement assembly = results.Assembly;

            if (assembly == null || IsFilterFile(Path.GetFileName(filename)))
            {
                Log.LogMessageFromResources("AssemblyAnalyzedSkipped");
                return(null);
            }

            // Create a new AssemblyConfig object
            asmConfig             = new AssemblyConfig();
            asmConfig.FileName    = filename;
            asmConfig.Name        = assembly.Name;
            asmConfig.Timestamp   = File.GetLastWriteTime(filename).Ticks;
            asmConfig.Assembly    = assembly;
            asmConfig.IsReference = false;

            // Generate a unique filename
            asmConfig.GenerateTypeSpecificationFileName(_intermediateOutputPath);

            _assembliesToStore.Add(asmConfig);
            _assembliesDirty = true;

            sw.Stop();
            Log.LogMessageFromResources("AssemblyAnalyzed", assembly.Types.Count, analyzer.UnresolvedAssemblies.Count, sw.Elapsed.TotalSeconds);

            return(assembly);
        }