/// <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); }
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); }