/// <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="context">The run context.</param> /// <param name="autoSaveMode">Indicates whether to auto-save the document back to the source, if autoFixMode is true.</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, RunContext context, bool autoSaveMode, bool ignoreResultsCache, string settingsPath) { Param.AssertNotNull(core, "core"); Param.AssertNotNull(codeProjects, "codeProjects"); Param.Ignore(resultsCache); Param.Ignore(context); Param.Ignore(autoSaveMode); Param.Ignore(ignoreResultsCache); Param.Ignore(settingsPath); this.core = core; this.projects = codeProjects; this.cache = resultsCache; this.context = context; this.autoSaveMode = autoSaveMode; this.ignoreResultsCache = ignoreResultsCache; this.settingsPath = settingsPath; }
private void Analyze(IList<CodeProject> projects, bool ignoreCache, string settingsPath, bool autoFix, bool autoSave) { Param.AssertNotNull(projects, "projects"); Param.Ignore(ignoreCache); Param.Ignore(settingsPath); Param.Ignore(autoFix); Param.Ignore(autoSave); // Indicate that we're analyzing. lock (this) { this.analyzing = true; this.cancel = false; this.runContext = new RunContext(autoFix); } // 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, this.runContext, autoSave, ignoreCache || autoFix, 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; this.runContext = null; } } }