private void Analyze(IList<CodeProject> projects, bool ignoreCache, string settingsPath) { Param.AssertNotNull(projects, "projects"); Param.Ignore(ignoreCache); Param.Ignore(settingsPath); // Indicate that we're analyzing. lock (this) { this.analyzing = true; this.cancel = false; } // Get the CPU count. #if DEBUGTHREADING // For debugging, only create a single worker thread. int threadCount = 1; #else // Create a maximum of two worker threads. int threadCount = Math.Max(GetCpuCount(), 2); #endif try { // Intialize each of the parsers. foreach (SourceParser parser in this.parsers.Values) { parser.PreParse(); // Initialize each of the enabled rules dictionaries for the analyzers. foreach (SourceAnalyzer analyzer in parser.Analyzers) { analyzer.PreAnalyze(); } } // Reads and writes the results cache. ResultsCache resultsCache = null; if (this.writeResultsCache) { resultsCache = new ResultsCache(this); } // Create a data object which will passed to each worker. StyleCopThread.Data data = new StyleCopThread.Data( this, projects, resultsCache, ignoreCache, settingsPath); // Initialize each of the projects before analysis. foreach (CodeProject project in projects) { StyleCopCore.InitializeProjectForAnalysis(project, data, resultsCache); } // Run until each of the parsers have completely finished analyzing all of the files. while (!this.Cancel) { // Reset the file enumeration index. data.ResetEmumerator(); // Run the worker threads and wait for them to complete. if (this.RunWorkerThreads(data, threadCount)) { // Analysis of all files has been completed. break; } // Increment the pass number for the next round. ++data.PassNumber; } // Save the cache files back to the disk. if (resultsCache != null) { resultsCache.Flush(); } // Finalize each of the parsers. foreach (SourceParser parser in this.parsers.Values) { parser.PostParse(); } // Clear the enabled rules lists from all analyzers since they are no longer needed. foreach (SourceParser parser in this.Parsers) { foreach (SourceAnalyzer analyzer in parser.Analyzers) { analyzer.PostAnalyze(); } } } catch (OutOfMemoryException) { // Don't log OutOfMemoryExceptions since there is no memory! throw; } catch (ThreadAbortException) { // The thread is being aborted. Stop analyzing the source files. } catch (Exception ex) { // We catch all exceptions here so that we can log a violation. Debug.Assert(false, "Unhandled exception while analyzing files: " + ex.Message); this.coreParser.AddViolation(null, 1, Rules.ExceptionOccurred, ex.GetType(), ex.Message); // Do not re-throw the exception as this can crash Visual Studio or the build system that StyleCop is running under. } finally { // Indicate that we're done analyzing. lock (this) { this.analyzing = false; } } }
/// <summary> /// Initializes the project to prepare it for analysis. /// </summary> /// <param name="project">The project to initialize.</param> /// <param name="data">The analysis data object.</param> /// <param name="cache">The file cache.</param> private static void InitializeProjectForAnalysis(CodeProject project, StyleCopThread.Data data, ResultsCache cache) { Param.AssertNotNull(project, "project"); Param.AssertNotNull(data, "data"); Param.Ignore(cache); // Get the status object for the project. ProjectStatus projectStatus = data.GetProjectStatus(project); Debug.Assert(projectStatus != null, "There is no status for the given project."); // Load the settings for the project. If the project already contains settings, use those. // Otherwise, load them from scratch. if (!project.SettingsLoaded) { project.Settings = data.GetSettings(project); project.SettingsLoaded = true; } // Load the project configuration from the cache and compare it to the // current project configuration. string configuration = cache == null ? null : cache.LoadProject(project); if (configuration == null) { projectStatus.IgnoreResultsCache = true; } else { projectStatus.IgnoreResultsCache = !StyleCopCore.CompareCachedConfiguration( project.Configuration, configuration); } if (cache != null && project.WriteCache) { cache.SaveProject(project); } }
private void Analyze(IList<CodeProject> projects, bool ignoreCache, string settingsPath) { lock (this) { this.analyzing = true; this.cancel = false; } int count = Math.Max(GetCpuCount(), 2); try { foreach (SourceParser parser in this.parsers.Values) { parser.PreParse(); foreach (SourceAnalyzer analyzer in parser.Analyzers) { analyzer.EnabledRules = new Dictionary<CodeProject, Dictionary<string, Rule>>(); analyzer.PreAnalyze(); } } ResultsCache resultsCache = null; if (this.writeResultsCache) { resultsCache = new ResultsCache(this); } StyleCopThread.Data data = new StyleCopThread.Data(this, projects, resultsCache, ignoreCache, settingsPath); foreach (CodeProject project in projects) { InitializeProjectForAnalysis(project, data, resultsCache); } while (!this.Cancel) { data.ResetEmumerator(); if (this.RunWorkerThreads(data, count)) { break; } data.PassNumber++; } if (resultsCache != null) { resultsCache.Flush(); } foreach (SourceParser parser2 in this.parsers.Values) { parser2.PostParse(); } foreach (SourceParser parser3 in this.Parsers) { foreach (SourceAnalyzer analyzer2 in parser3.Analyzers) { analyzer2.EnabledRules = null; analyzer2.PostAnalyze(); } } } catch (OutOfMemoryException) { throw; } catch (ThreadAbortException) { } catch (Exception exception) { this.coreParser.AddViolation(null, 1, Rules.ExceptionOccurred, new object[] { exception.GetType(), exception.Message }); } finally { lock (this) { this.analyzing = false; } } }
/// <summary> /// Initializes a new instance of the Data class. /// </summary> /// <param name="core">The StyleCop core instance.</param> /// <param name="codeProjects">The list of code projects to analyze.</param> /// <param name="resultsCache">The results cache.</param> /// <param name="ignoreResultsCache">True to ignore the results cache.</param> /// <param name="settingsPath">The path to the settings to use during analysis.</param> public Data( StyleCopCore core, IList<CodeProject> codeProjects, ResultsCache resultsCache, bool ignoreResultsCache, string settingsPath) { Param.AssertNotNull(core, "core"); Param.AssertNotNull(codeProjects, "codeProjects"); Param.Ignore(resultsCache); Param.Ignore(ignoreResultsCache); Param.Ignore(settingsPath); this.core = core; this.projects = codeProjects; this.cache = resultsCache; this.ignoreResultsCache = ignoreResultsCache; this.settingsPath = settingsPath; }
private static void InitializeProjectForAnalysis(CodeProject project, StyleCopThread.Data data, ResultsCache cache) { ProjectStatus projectStatus = data.GetProjectStatus(project); if (!project.SettingsLoaded) { project.Settings = data.GetSettings(project); project.SettingsLoaded = true; } string flagList = (cache == null) ? null : cache.LoadProject(project); if (flagList == null) { projectStatus.IgnoreResultsCache = true; } else { projectStatus.IgnoreResultsCache = !CompareCachedConfiguration(project.Configuration, flagList); } if ((cache != null) && project.WriteCache) { cache.SaveProject(project); } }