/// <summary> /// Initializes a new instance of the StyleCopThreadCompletedEventArgs class. /// </summary> /// <param name="data">The thread data.</param> public StyleCopThreadCompletedEventArgs(StyleCopThread.Data data) { Param.AssertNotNull(data, "data"); this.data = data; }
private void Analyze(IList<CodeProject> projects, bool ignoreCache, string settingsPath) { Param.AssertNotNull(projects, "projects"); Param.Ignore(ignoreCache); Param.Ignore(settingsPath); StyleCopTrace.In(projects, ignoreCache, settingsPath); // Indicate that we're analyzing. lock (this) { this.analyzing = true; this.cancel = false; } //// TODO When we move to FRamework 4 we can re-introduce the threads and use the CountdownEvent to synchronize. //// 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.Min(CpuCount, 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; } } StyleCopTrace.Out(); }