예제 #1
0
            /// <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;
            }
예제 #2
0
        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;
                }
            }
        }