예제 #1
0
        /// <summary>
        /// Runs the list of analyzers against the given document.
        /// </summary>
        /// <param name="document">The document to analyze.</param>
        /// <param name="parser">The parser that created the document.</param>
        /// <param name="analyzers">The list of analyzsers to run against the document.</param>
        private void RunAnalyzers(
            ICodeDocument document, SourceParser parser, IEnumerable <SourceAnalyzer> analyzers)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(analyzers, "analyzers");

            if (analyzers != null)
            {
                if (parser.SkipAnalysisForDocument(document))
                {
                    this.data.Core.SignalOutput(
                        MessageImportance.Normal,
                        string.Format(CultureInfo.CurrentCulture, "Skipping {0}...", document.SourceCode.Name));
                }
                else
                {
                    // Loop through each of the analyzers attached to the parser.
                    foreach (SourceAnalyzer analyzer in analyzers)
                    {
                        // Make sure the user hasn't cancelled us.
                        if (this.data.Core.Cancel)
                        {
                            break;
                        }

                        // Only run the analyzers associated with the current parser.
                        if (analyzer.Parser == parser)
                        {
                            SourceParser.ClearAnalyzerTags(document);
                            try
                            {
                                // Check whether we are running in auto-fix mode, in which case we should call the
                                // AutoFixDocument method on analyzers that support it. Otherwise, we are simply running
                                // the rules and we should call the AnalyzeDocument method instead.
                                if (this.data.RunContext.AutoFix)
                                {
                                    analyzer.AutoFixDocument(document);
                                }
                                else
                                {
                                    analyzer.AnalyzeDocument(document);
                                }
                            }
                            catch (System.Exception)
                            {
                                string details = string.Format(
                                    CultureInfo.CurrentCulture,
                                    "Exception thrown by analyzer '{0}' while processing '{1}'.",
                                    analyzer.Name,
                                    document.SourceCode.Path);

                                this.data.Core.SignalOutput(MessageImportance.High, details);
                                throw;
                            }
                        }
                    }
                }
            }
        }
예제 #2
0
        /// <summary>
        /// Sets the parser that this analyzer is attached to.
        /// </summary>
        /// <param name="item">
        /// The parser object that this analyzer is attached to.
        /// </param>
        internal void SetParser(SourceParser item)
        {
            Param.Ignore(item);

            // Set the reference to the parser object.
            this.parser = item;
        }
        /// <summary>
        /// Invoked when a new parser is loaded.
        /// </summary>
        /// <param name="parser">
        /// The new parser.
        /// </param>
        public override void AddParser(SourceParser parser)
        {
            Param.RequireNotNull(parser, "parser");

            // Add the parser to the code extensions table.
            ICollection<string> fileTypesForParser = parser.FileTypes;

            if (fileTypesForParser != null)
            {
                // Loop through each of the file types.
                foreach (string fileTypeForParser in fileTypesForParser)
                {
                    if (fileTypeForParser != null)
                    {
                        List<SourceParser> list = null;
                        if (!this.fileTypes.TryGetValue(fileTypeForParser, out list))
                        {
                            list = new List<SourceParser>(1);
                            this.fileTypes.Add(fileTypeForParser, list);
                        }

                        list.Add(parser);
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// Invoked when a new parser is loaded.
        /// </summary>
        /// <param name="parser">The new parser.</param>
        public override void AddParser(SourceParser parser)
        {
            Param.RequireNotNull(parser, "parser");

            // Add the parser to the code extensions table.
            ICollection <string> fileTypesForParser = parser.FileTypes;

            if (fileTypesForParser != null)
            {
                // Loop through each of the file types.
                foreach (string fileTypeForParser in fileTypesForParser)
                {
                    if (fileTypeForParser != null)
                    {
                        List <SourceParser> list = null;
                        if (!this.fileTypes.TryGetValue(fileTypeForParser, out list))
                        {
                            list = new List <SourceParser>(1);
                            this.fileTypes.Add(fileTypeForParser, list);
                        }

                        list.Add(parser);
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Runs the analyzers against the given document.
        /// </summary>
        /// <param name="document">
        /// The document to analyze.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="analyzers">
        /// The analyzers to run against the document.
        /// </param>
        /// <param name="passNumber">
        /// The current pass number.
        /// </param>
        /// <returns>
        /// Returns true if analysis was run, or false if analysis was delayed until the next pass.
        /// </returns>
        private bool TestAndRunAnalyzers(CodeDocument document, SourceParser parser, IEnumerable <SourceAnalyzer> analyzers, int passNumber)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(analyzers);
            Param.Ignore(passNumber);
            StyleCopTrace.In(document, parser, analyzers, passNumber);

            if (analyzers == null)
            {
                return(StyleCopTrace.Out(true));
            }

            // Determine whether any of the analyzers wish to delay analysis until the next pass.
            bool delay = false;

            foreach (SourceAnalyzer analyzer in analyzers)
            {
                if (analyzer.DelayAnalysis(document, passNumber))
                {
                    delay = true;
                    break;
                }
            }

            if (!delay)
            {
                this.RunAnalyzers(document, parser, analyzers);
            }

            return(StyleCopTrace.Out(!delay));
        }
예제 #6
0
        /// <summary>
        /// Runs the analyzers against the given document.
        /// </summary>
        /// <param name="document">The document to analyze.</param>
        /// <param name="parser">The parser that created the document.</param>
        /// <param name="analyzers">The analyzers to run against the document.</param>
        /// <param name="passNumber">The current pass number.</param>
        /// <returns>Returns true if analysis was run, or false if analysis was delayed until the next pass.</returns>
        private bool TestAndRunAnalyzers(
            ICodeDocument document, SourceParser parser, IEnumerable <SourceAnalyzer> analyzers, int passNumber)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(analyzers);
            Param.Ignore(passNumber);

            if (analyzers == null)
            {
                return(true);
            }

            // Determine whether any of the analyzers wish to delay parsing until the next pass.
            bool delay = false;

            foreach (SourceAnalyzer analyzer in analyzers)
            {
                if (!this.data.RunContext.AutoFix)
                {
                    if (analyzer.DelayAnalysis(document, passNumber))
                    {
                        delay = true;
                        break;
                    }
                }
            }

            if (!delay)
            {
                this.RunAnalyzers(document, parser, analyzers);
            }

            return(!delay);
        }
예제 #7
0
        /// <summary>
        /// Initializes a new instance of the CodeFile class.
        /// </summary>
        /// <param name="path">
        /// The path to the code file.
        /// </param>
        /// <param name="project">
        /// The project that contains this file.
        /// </param>
        /// <param name="parser">
        /// The parser that created this file object.
        /// </param>
        /// <param name="configurations">
        /// The list of configurations for the file.
        /// </param>
        public CodeFile(string path, CodeProject project, SourceParser parser, IEnumerable <Configuration> configurations)
            : base(project, parser, configurations)
        {
            Param.RequireNotNull(path, "path");
            Param.RequireNotNull(project, "project");
            Param.RequireNotNull(parser, "parser");
            Param.Ignore(configurations);

            // If this is not a full path, then we need to add the current directory.
            if (!path.StartsWith(@"\\", StringComparison.Ordinal) && path.Length >= 2 && path[1] != ':')
            {
                path = System.IO.Path.GetFullPath(path);
            }

            // BugFix 6777 - Update the path field after correcting the local path variable
            this.path   = path;
            this.name   = System.IO.Path.GetFileName(path);
            this.folder = StyleCopCore.CleanPath(System.IO.Path.GetDirectoryName(path));

            // Strip out the file extension.
            this.fileType = System.IO.Path.GetExtension(this.name).ToUpperInvariant();
            if (this.fileType.Length > 0)
            {
                this.fileType = this.fileType.Substring(1);
            }
        }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="configurations">The list of configurations for the file.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser, IEnumerable<Configuration> configurations)
     : base(path, project, parser, configurations)
 {
     Param.AssertNotNull(path, "path");
     Param.AssertNotNull(project, "project");
     Param.AssertNotNull(parser, "parser");
     Param.Ignore(configurations);
 }
예제 #9
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="configurations">The list of configurations for the file.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser, IEnumerable <Configuration> configurations)
     : base(path, project, parser, configurations)
 {
     Param.AssertNotNull(path, "path");
     Param.AssertNotNull(project, "project");
     Param.AssertNotNull(parser, "parser");
     Param.Ignore(configurations);
 }
예제 #10
0
        /// <summary>
        /// Initializes a new instance of the SourceCode class.
        /// </summary>
        /// <param name="project">
        /// The project that contains this document.
        /// </param>
        /// <param name="parser">
        /// The parser that created this document.
        /// </param>
        protected SourceCode(CodeProject project, SourceParser parser)
        {
            Param.RequireNotNull(project, "project");
            Param.RequireNotNull(parser, "parser");

            this.project = project;
            this.parser = parser;
        }
예제 #11
0
        /// <summary>
        /// Initializes a new instance of the SourceCode class.
        /// </summary>
        /// <param name="project">
        /// The project that contains this document.
        /// </param>
        /// <param name="parser">
        /// The parser that created this document.
        /// </param>
        protected SourceCode(CodeProject project, SourceParser parser)
        {
            Param.RequireNotNull(project, "project");
            Param.RequireNotNull(parser, "parser");

            this.project = project;
            this.parser  = parser;
        }
예제 #12
0
        /// <summary>
        /// Runs the list of analyzers against the given document.
        /// </summary>
        /// <param name="document">
        /// The document to analyze.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="analyzers">
        /// The list of analyzers to run against the document.
        /// </param>
        private void RunAnalyzers(CodeDocument document, SourceParser parser, IEnumerable <SourceAnalyzer> analyzers)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(analyzers, "analyzers");
            StyleCopTrace.In(document, parser, analyzers);

            if (analyzers != null)
            {
                if (parser.SkipAnalysisForDocument(document.SourceCode))
                {
                    string format = string.Format(CultureInfo.CurrentCulture, "Skipping: {0} - {1}", document.SourceCode.Project.Location.SubstringAfterLast('\\'), GetRelativeFileName(document.SourceCode));
                    this.data.Core.SignalOutput(MessageImportance.Normal, format);
                }
                else
                {
                    // Loop through each of the parser's analyzers.
                    // Only call analyzers that are also in the enabled list.
                    foreach (SourceAnalyzer analyzer in parser.Analyzers)
                    {
                        SourceAnalyzer localAnalyzer = analyzer;
                        if (analyzers.Any(enabledAnalyzers => enabledAnalyzers.Id == localAnalyzer.Id))
                        {
                            // Make sure the user hasn't cancelled us.
                            if (this.data.Core.Cancel)
                            {
                                break;
                            }

                            SourceParser.ClearAnalyzerTags(document);
                            try
                            {
                                if (analyzer.DoAnalysis(document))
                                {
                                    analyzer.AnalyzeDocument(document);
                                }
                            }
                            catch (Exception ex)
                            {
                                StringBuilder details = new StringBuilder();
                                details.AppendLine(string.Format(CultureInfo.CurrentCulture, "Exception thrown by analyzer '{0}' while processing '{1}'.", analyzer.Name, document.SourceCode.Path));

                                // Add exception message for help on bugfix.
                                if (!string.IsNullOrEmpty(ex.Message))
                                {
                                    details.AppendLine(string.Format(CultureInfo.CurrentCulture, "Exception message : {0}", ex.Message));
                                }

                                this.data.Core.SignalOutput(MessageImportance.High, details.ToString());
                                throw;
                            }
                        }
                    }
                }
            }

            StyleCopTrace.Out();
        }
        /// <summary>
        /// Retrieves a <see cref="SourceCode" /> object corresponding to the given path.
        /// </summary>
        /// <param name="path">The path to the source code object.</param>
        /// <param name="project">The project which contains the source code object.</param>
        /// <param name="parser">The parser for the source code type.</param>
        /// <param name="context">Optional context.</param>
        /// <returns>Returns the source code object.</returns>
        private SourceCode SourceCodeFactory(string path, CodeProject project, SourceParser parser, object context)
        {
            Param.Ignore(path, project, parser, context);

            int index = (int)context;
            Assert.IsTrue(index >= 0 && index < StaticSource.Sources.Length, "The index is out of range.");

            return new ObjectBasedSourceCode(project, parser, index);
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="ObjectBasedSourceCode"/> class.
        /// </summary>
        /// <param name="project">
        /// The project.
        /// </param>
        /// <param name="parser">
        /// The parser.
        /// </param>
        /// <param name="index">
        /// The index.
        /// </param>
        public ObjectBasedSourceCode(CodeProject project, SourceParser parser, int index)
            : base(project, parser)
        {
            Param.Ignore(project);
            Param.Ignore(parser);
            Param.AssertValueBetween(index, 0, StaticSource.Sources.Length - 1, "Out of range.");

            this.index = index;
        }
예제 #15
0
        public CodeText(string text, CodeProject project, SourceParser parser, IEnumerable<Configuration> configurations)
            : base(project, parser, configurations)
        {
            Param.RequireNotNull(text, "text");
            Param.RequireNotNull(project, "project");
            Param.RequireNotNull(parser, "parser");
            Param.Ignore(configurations);

            this.text = text;
        }
예제 #16
0
        /// <summary>
        /// Opens the results cache for the given source code document.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code document.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="item">
        /// Returns the node from the results cache for this code document.
        /// </param>
        /// <returns>
        /// Returns the results cache.
        /// </returns>
        private XmlDocument OpenResultsCache(SourceCode sourceCode, SourceParser parser, out XmlNode item)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parser, "parser");

            item = null;

            XmlDocument doc = null;

            try
            {
                lock (this)
                {
                    // Determine whether this results cache is already in our list.
                    if (this.documentHash.TryGetValue(sourceCode.Project.Location, out doc))
                    {
                        // Now pull out the section for this source code document.
                        item =
                            doc.DocumentElement.SelectSingleNode(
                                string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", sourceCode.Name, parser.Id));
                    }
                    else
                    {
                        doc = this.core.Environment.LoadResultsCache(sourceCode.Project.Location);
                        if (doc != null)
                        {
                            // Get the version and make sure it matches.
                            XmlElement node = doc["stylecopresultscache"]["version"];
                            if (node.InnerText == ResultsCache.Version)
                            {
                                // Now pull out the section for this source code document.
                                item =
                                    doc.DocumentElement.SelectSingleNode(
                                        string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", sourceCode.Name, parser.Id));
                            }
                            else
                            {
                                // Since the version does not match, ignore this document.
                                doc = null;
                            }
                        }
                    }
                }
            }
            catch (XmlException)
            {
                doc = null;
            }
            catch (NullReferenceException)
            {
                doc = null;
            }

            return(doc);
        }
예제 #17
0
        public Source(CodeProject project, SourceParser parser, string source, string sourceName)
            : base(project, parser)
        {
            Param.Ignore(project);
            Param.Ignore(parser);
            Param.AssertNotNull(source, "source");
            Param.AssertNotNull(sourceName, "sourceName");

            this.source = source;
            this.sourceName = sourceName;
        }
예제 #18
0
        /// <summary>
        /// Loads results for the given source code document from the cache.
        /// </summary>
        /// <param name="sourceCode">The source code to load.</param>
        /// <param name="parser">The parser that created this document.</param>
        /// <param name="writeTime">The last write time of the document.</param>
        /// <param name="settingsTimeStamp">The time when the settings were last updated.</param>
        /// <returns>Returns true if the results were loaded from the cache.</returns>
        public bool LoadResults(SourceCode sourceCode, SourceParser parser, DateTime writeTime, DateTime settingsTimeStamp)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(writeTime);
            Param.Ignore(settingsTimeStamp);

            bool success = false;

            lock (this)
            {
                XmlNode     item = null;
                XmlDocument doc  = this.OpenResultsCache(sourceCode, parser, out item);

                if (doc != null && item != null)
                {
                    try
                    {
                        // Check the settings file timestamp.
                        XmlElement settingsNode = item["settings"];
                        if (settingsNode != null && IsNodeUpToDate(settingsNode, settingsTimeStamp))
                        {
                            // Get the timestamp and make sure the file has not been changed
                            // since this cache was written.
                            if (IsNodeUpToDate(item, writeTime))
                            {
                                XmlNode violations = item.SelectSingleNode("violations");
                                if (violations != null)
                                {
                                    if (parser.ImportViolations(sourceCode, violations))
                                    {
                                        success = true;
                                    }
                                }
                            }
                        }
                    }
                    catch (XmlException)
                    {
                    }

                    if (!this.documentHash.ContainsKey(sourceCode.Project.Location))
                    {
                        this.documentHash.Add(sourceCode.Project.Location, doc);
                    }
                }
            }

            return(success);
        }
예제 #19
0
        /// <summary>
        /// Loads results for the given source code document from the cache.
        /// </summary>
        /// <param name="sourceCode">The source code to load.</param>
        /// <param name="parser">The parser that created this document.</param>
        /// <param name="writeTime">The last write time of the document.</param>
        /// <param name="settingsTimeStamp">The time when the settings were last updated.</param>
        /// <returns>Returns true if the results were loaded from the cache.</returns>
        public bool LoadResults(SourceCode sourceCode, SourceParser parser, DateTime writeTime, DateTime settingsTimeStamp)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(writeTime);
            Param.Ignore(settingsTimeStamp);

            bool success = false;

            lock (this)
            {
                XmlNode item = null;
                XmlDocument doc = this.OpenResultsCache(sourceCode, parser, out item);

                if (doc != null && item != null)
                {
                    try
                    {
                        // Check the settings file timestamp.
                        XmlElement settingsNode = item["settings"];
                        if (settingsNode != null && IsNodeUpToDate(settingsNode, settingsTimeStamp))
                        {
                            // Get the timestamp and make sure the file has not been changed
                            // since this cache was written.
                            if (IsNodeUpToDate(item, writeTime))
                            {
                                XmlNode violations = item.SelectSingleNode("violations");
                                if (violations != null)
                                {
                                    if (parser.ImportViolations(sourceCode, violations))
                                    {
                                        success = true;
                                    }
                                }
                            }
                        }
                    }
                    catch (XmlException)
                    {
                    }

                    if (!this.documentHash.ContainsKey(sourceCode.Project.Location))
                    {
                        this.documentHash.Add(sourceCode.Project.Location, doc);
                    }
                }
            }

            return success;
        }
예제 #20
0
        /// <summary>
        /// Sets the AnalyzeDesignerFiles property on the C# parser.
        /// </summary>
        /// <param name="settings">The settings collection.</param>
        /// <param name="nodeText">The text of the setting from the settings file.</param>
        private static void LoadAnalyzeDesignerFilesSetting(Settings settings, string nodeText)
        {
            Param.AssertNotNull(settings, "settings");
            Param.AssertValidString(nodeText, "nodeText");

            SourceParser parser = settings.Core.GetParser("StyleCop.CSharp.CsParser");

            if (parser != null)
            {
                PropertyDescriptor <bool> propertyDescriptor = parser.PropertyDescriptors["AnalyzeDesignerFiles"] as PropertyDescriptor <bool>;
                if (propertyDescriptor != null)
                {
                    settings.SetAddInSettingInternal(parser, new BooleanProperty(propertyDescriptor, nodeText != "0"));
                }
            }
        }
예제 #21
0
        /// <summary>
        /// Loads parser settings from the document.
        /// </summary>
        /// <param name="document">
        /// The settings document.
        /// </param>
        /// <param name="settings">
        /// Stores the settings.
        /// </param>
        private static void LoadParserSettings(XmlDocument document, Settings settings)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(settings, "settings");

            XmlNodeList parsersNodes = document.DocumentElement.SelectNodes("Parsers/Parser");

            if (parsersNodes != null && parsersNodes.Count > 0)
            {
                foreach (XmlNode parserNode in parsersNodes)
                {
                    XmlAttribute parserId = parserNode.Attributes["ParserId"];
                    if (parserId != null && !string.IsNullOrEmpty(parserId.Value))
                    {
                        string parserName = parserId.Value;
                        if (parserName.Equals("Microsoft.SourceAnalysis.CSharp.CsParser", StringComparison.Ordinal))
                        {
                            parserName = "StyleCop.CSharp.CsParser";
                        }

                        // Get the parser instance.
                        SourceParser parserInstance = settings.Core.GetParser(parserName);
                        if (parserInstance != null)
                        {
                            // Get the parser settings object for this parser or create a new one.
                            AddInPropertyCollection settingsForParser = settings.GetAddInSettings(parserInstance);

                            if (settingsForParser == null)
                            {
                                settingsForParser = new AddInPropertyCollection(parserInstance);
                                settings.SetAddInSettings(settingsForParser);
                            }

                            // Load the settings for this parser.
                            XmlNode parserSettingsNode = parserNode["ParserSettings"];
                            if (parserSettingsNode != null)
                            {
                                LoadPropertyCollection(parserSettingsNode, settingsForParser, parserInstance.PropertyDescriptors, null);
                            }

                            // Load any rule settings for the parser.
                            LoadRulesSettings(parserNode, settingsForParser, parserInstance.PropertyDescriptors);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// Creates a new <see cref="CodeFile"/> instance with the given values.
        /// </summary>
        /// <param name="path">The path to the code file.</param>
        /// <param name="project">The project that contains this file.</param>
        /// <param name="parser">The parser that created this file object.</param>
        /// <param name="context">Optional context information.</param>
        /// <returns>Returns the newly created <see cref="CodeFile"/>.</returns>
        protected override CodeFile CreateCodeFile(string path, CodeProject project, SourceParser parser, object context)
        {
            Param.Ignore(path, project, parser, context);

            ProjectItem p = context as ProjectItem;
            if (p != null)
            {
                return new VisualStudioCodeFile(path, project, parser, p);
            }

            Document d = context as Document;
            if (d != null)
            {
                return new VisualStudioCodeFile(path, project, parser, d);
            }

            return new VisualStudioCodeFile(path, project, parser);
        }
예제 #23
0
        /// <summary>
        /// Loads parser settings from the document.
        /// </summary>
        /// <param name="documentRoot">The root node of the settings document.</param>
        /// <param name="settings">Stores the settings.</param>
        private static void LoadParserSettings(XmlNode documentRoot, Settings settings)
        {
            Param.AssertNotNull(documentRoot, "documentRoot");
            Param.AssertNotNull(settings, "settings");

            XmlNodeList parsersNodes = documentRoot.SelectNodes("Parsers/Parser");

            if (parsersNodes != null && parsersNodes.Count > 0)
            {
                foreach (XmlNode parserNode in parsersNodes)
                {
                    XmlAttribute parserId = parserNode.Attributes["ParserId"];
                    if (parserId != null && !string.IsNullOrEmpty(parserId.Value))
                    {
                        string parserName = ConvertLegacyAddInName(parserId.Value);

                        // Get the parser instance.
                        SourceParser parserInstance = settings.Core.GetParser(parserName);
                        if (parserInstance != null)
                        {
                            // Get the parser settings object for this parser or create a new one.
                            AddInPropertyCollection settingsForParser = settings.GetAddInSettings(parserInstance);

                            if (settingsForParser == null)
                            {
                                settingsForParser = new AddInPropertyCollection(parserInstance);
                                settings.SetAddInSettings(settingsForParser);
                            }

                            // Load the settings for this parser.
                            XmlNode parserSettingsNode = parserNode["ParserSettings"];
                            if (parserSettingsNode != null)
                            {
                                LoadPropertyCollection(parserSettingsNode, settingsForParser, parserInstance.PropertyDescriptors, null);
                            }

                            // Load any rule settings for the parser.
                            LoadRulesSettings(parserNode, settingsForParser, parserInstance.PropertyDescriptors);
                        }
                    }
                }
            }
        }
예제 #24
0
        /// <summary>
        /// Initializes a new instance of the SourceAnalyzer class.
        /// </summary>
        protected SourceAnalyzer()
        {
            // Get the SourceAnalyzer attribute from the type.
            object[] attributes = this.GetType().GetCustomAttributes(typeof(SourceAnalyzerAttribute), true);
            if (attributes == null || attributes.Length == 0)
            {
                throw new ArgumentException(Strings.SourceAnalyzerAttributeMissing);
            }

            // Make sure the parser type is set.
            SourceAnalyzerAttribute attribute = (SourceAnalyzerAttribute)attributes[0];

            if (attribute.ParserType == null)
            {
                throw new ArgumentException(Strings.SourceAnalyzerAttributeMissing);
            }

            // Set the parser ID.
            this.parserId = SourceParser.GetIdFromAddInType(attribute.ParserType);
        }
예제 #25
0
        /// <summary>
        /// Creates a new <see cref="CodeFile"/> instance with the given values.
        /// </summary>
        /// <param name="path">The path to the code file.</param>
        /// <param name="project">The project that contains this file.</param>
        /// <param name="parser">The parser that created this file object.</param>
        /// <param name="context">Optional context information.</param>
        /// <returns>Returns the newly created <see cref="CodeFile"/>.</returns>
        protected override CodeFile CreateCodeFile(string path, CodeProject project, SourceParser parser, object context)
        {
            Param.Ignore(path, project, parser, context);

            ProjectItem p = context as ProjectItem;

            if (p != null)
            {
                return(new VisualStudioCodeFile(path, project, parser, p));
            }

            Document d = context as Document;

            if (d != null)
            {
                return(new VisualStudioCodeFile(path, project, parser, d));
            }

            return(new VisualStudioCodeFile(path, project, parser));
        }
예제 #26
0
        /// <summary>
        /// Exports the violations found within this document into the given xml node.
        /// </summary>
        /// <param name="document">The document containing the violations.</param>
        /// <param name="violationsDocument">The xml document in which to store the violation information.</param>
        /// <param name="parentNode">The parent node within this xml document under which to store the violation information.</param>
        internal static void ExportViolations(ICodeDocument document, XmlDocument violationsDocument, XmlNode parentNode)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(violationsDocument, "violationsDocument");
            Param.AssertNotNull(parentNode, "parentNode");

            if (document.DocumentContents != null)
            {
                SourceParser.ExportElementViolations(document.DocumentContents, violationsDocument, parentNode);
            }

            if (document.SourceCode != null)
            {
                // Add the violations from the source code.
                foreach (Violation violation in document.SourceCode.Violations)
                {
                    SourceParser.ExportViolation(violation, violationsDocument, parentNode);
                }
            }
        }
예제 #27
0
        /// <summary>
        /// Exports the violations found within this document into the given xml node.
        /// </summary>
        /// <param name="element">The element containing the violations to export.</param>
        /// <param name="violationsDocument">The xml document in which to store the violation information.</param>
        /// <param name="parentNode">The parent node within this xml document under which to store the violation information.</param>
        private static void ExportElementViolations(ICodeElement element, XmlDocument violationsDocument, XmlNode parentNode)
        {
            Param.AssertNotNull(element, "element");
            Param.AssertNotNull(violationsDocument, "violationsDocument");
            Param.AssertNotNull(parentNode, "parentNode");

            // Add the violations from this element.
            foreach (Violation violation in element.Violations)
            {
                SourceParser.ExportViolation(violation, violationsDocument, parentNode);
            }

            // Add this violations from this element's children.
            IEnumerable <ICodeElement> children = element.ChildCodeElements;

            if (children != null)
            {
                foreach (ICodeElement child in children)
                {
                    SourceParser.ExportElementViolations(child, violationsDocument, parentNode);
                }
            }
        }
예제 #28
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser)
     : base(path, project, parser, null)
 {
     Param.Ignore(path, project, parser);
 }
예제 #29
0
 /// <summary>
 /// Initializes a new instance of the CodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 public CodeFile(string path, CodeProject project, SourceParser parser)
     : this(path, project, parser, null)
 {
     Param.Ignore(path, project, parser);
 }
예제 #30
0
        /// <summary>
        /// Saves the given code document results into a cache document.
        /// </summary>
        /// <param name="document">
        /// The document to save.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="settingsTimeStamp">
        /// The time when the settings were last updated.
        /// </param>
        /// <returns>
        /// Returns true if the document was saved.
        /// </returns>
        public bool SaveDocumentResults(CodeDocument document, SourceParser parser, DateTime settingsTimeStamp)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(settingsTimeStamp);

            bool success = false;

            lock (this)
            {
                try
                {
                    XmlDocument xml;
                    if (!this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                    {
                        XmlNode temp;
                        xml = this.OpenResultsCache(document.SourceCode, parser, out temp);
                        if (xml != null)
                        {
                            this.documentHash.Add(document.SourceCode.Project.Location, xml);
                        }
                    }
                    else
                    {
                        xml = this.documentHash[document.SourceCode.Project.Location];
                    }

                    if (xml != null)
                    {
                        XmlNode remove =
                            xml.DocumentElement.SelectSingleNode(
                                string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", document.SourceCode.Name, parser.Id));
                        if (remove != null)
                        {
                            xml.DocumentElement.RemoveChild(remove);
                        }
                    }
                    else
                    {
                        xml = new XmlDocument();

                        // Create the document node.
                        xml.AppendChild(xml.CreateElement("stylecopresultscache"));

                        // Add the version.
                        XmlNode versionNode = xml.CreateElement("version");
                        xml.DocumentElement.AppendChild(versionNode);
                        versionNode.InnerText = ResultsCache.Version;

                        if (this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                        {
                            this.documentHash.Remove(document.SourceCode.Project.Location);
                        }

                        this.documentHash.Add(document.SourceCode.Project.Location, xml);
                    }

                    XmlNode      root = xml.CreateElement("sourcecode");
                    XmlAttribute name = xml.CreateAttribute("name");
                    name.Value = document.SourceCode.Name;
                    root.Attributes.Append(name);
                    xml.DocumentElement.AppendChild(root);

                    // Create the timestamps node.
                    // We need to store the timestamp of all files that were used to create the violation.
                    // Parser, Rules, settings, source file, spell checker, and dictionaries.
                    XmlElement node = xml.CreateElement("timestamps");
                    root.AppendChild(node);

                    this.AddTimestampToXml(xml, node, "styleCop", this.core.TimeStamp);

                    this.AddTimestampToXml(xml, node, "settingsFile", settingsTimeStamp);

                    // Stores the last write time of the source code.
                    this.AddTimestampToXml(xml, node, "sourceFile", document.SourceCode.TimeStamp);

                    // Store all the rules and parser timestamps
                    this.AddTimestampToXml(xml, node, "parser", document.SourceCode.Parser.TimeStamp);

                    foreach (SourceAnalyzer analyzer in document.SourceCode.Parser.Analyzers)
                    {
                        this.AddTimestampToXml(xml, node, analyzer.Id, analyzer.TimeStamp);
                        this.AddHashCodeToXml(xml, node, analyzer.Id + ".FilesHashCode", analyzer.GetDependantFilesHashCode(document.SourceCode.Project.Culture));
                    }

                    // Add the parser ID attribute.
                    if (document.SourceCode.Parser != null)
                    {
                        XmlAttribute attribute = xml.CreateAttribute("parser");
                        root.Attributes.Append(attribute);
                        attribute.Value = document.SourceCode.Parser.Id;
                    }

                    // Create the violations node.
                    node = xml.CreateElement("violations");
                    root.AppendChild(node);

                    // Add the violations.
                    SourceParser.ExportViolations(document, xml, node);

                    success = true;
                }
                catch (XmlException)
                {
                }
            }

            return(success);
        }
예제 #31
0
        /// <summary>
        /// Opens the results cache for the given source code document.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code document.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="item">
        /// Returns the node from the results cache for this code document.
        /// </param>
        /// <returns>
        /// Returns the results cache.
        /// </returns>
        private XmlDocument OpenResultsCache(SourceCode sourceCode, SourceParser parser, out XmlNode item)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parser, "parser");

            item = null;

            XmlDocument doc = null;

            try
            {
                lock (this)
                {
                    // Determine whether this results cache is already in our list.
                    if (this.documentHash.TryGetValue(sourceCode.Project.Location, out doc))
                    {
                        // Now pull out the section for this source code document.
                        item =
                            doc.DocumentElement.SelectSingleNode(
                                string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", sourceCode.Name, parser.Id));
                    }
                    else
                    {
                        doc = this.core.Environment.LoadResultsCache(sourceCode.Project.Location);
                        if (doc != null)
                        {
                            // Get the version and make sure it matches.
                            XmlElement node = doc["stylecopresultscache"]["version"];
                            if (node.InnerText == ResultsCache.Version)
                            {
                                // Now pull out the section for this source code document.
                                item =
                                    doc.DocumentElement.SelectSingleNode(
                                        string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", sourceCode.Name, parser.Id));
                            }
                            else
                            {
                                // Since the version does not match, ignore this document.
                                doc = null;
                            }
                        }
                    }
                }
            }
            catch (XmlException)
            {
                doc = null;
            }
            catch (NullReferenceException)
            {
                doc = null;
            }

            return doc;
        }
예제 #32
0
        /// <summary>
        /// Loads results for the given source code document from the cache.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code to load.
        /// </param>
        /// <param name="parser">
        /// The parser that created this document.
        /// </param>
        /// <param name="writeTime">
        /// The last write time of the document.
        /// </param>
        /// <param name="settingsTimestamp">
        /// The time when the settings were last updated.
        /// </param>
        /// <returns>
        /// Returns true if the results were loaded from the cache.
        /// </returns>
        public bool LoadResults(SourceCode sourceCode, SourceParser parser, DateTime writeTime, DateTime settingsTimestamp)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(writeTime);
            Param.Ignore(settingsTimestamp);

            lock (this)
            {
                XmlNode item = null;
                XmlDocument doc = this.OpenResultsCache(sourceCode, parser, out item);

                if (doc != null && item != null)
                {
                    if (!this.documentHash.ContainsKey(sourceCode.Project.Location))
                    {
                        this.documentHash.Add(sourceCode.Project.Location, doc);
                    }

                    try
                    {
                        // Check the timestamps of all the files.
                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/styleCop"), this.core.TimeStamp))
                        {
                            return false;
                        }

                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/settingsFile"), settingsTimestamp))
                        {
                            return false;
                        }

                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/sourceFile"), writeTime))
                        {
                            return false;
                        }

                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/parser"), parser.TimeStamp))
                        {
                            return false;
                        }

                        foreach (SourceAnalyzer analyzer in parser.Analyzers)
                        {
                            if (!IsNodeUpToDate(item.SelectSingleNode(string.Concat("timestamps/", analyzer.Id)), analyzer.TimeStamp))
                            {
                                return false;
                            }

                            if (
                                !IsNodeUpToDate(
                                    item.SelectSingleNode(string.Concat("timestamps/", analyzer.Id + ".FilesHashCode")), 
                                    analyzer.GetDependantFilesHashCode(sourceCode.Project.Culture)))
                            {
                                return false;
                            }
                        }

                        XmlNode violations = item.SelectSingleNode("violations");
                        if (violations != null)
                        {
                            if (parser.ImportViolations(sourceCode, violations))
                            {
                                return true;
                            }
                        }
                    }
                    catch (XmlException)
                    {
                    }
                }
            }

            return false;
        }
예제 #33
0
 /// <summary>
 /// Initializes a new instance of the SourceCode class.
 /// </summary>
 /// <param name="project">
 /// The project that contains this document.
 /// </param>
 /// <param name="parser">
 /// The parser that created this document.
 /// </param>
 /// <param name="configurations">
 /// The list of configurations for the document.
 /// </param>
 protected SourceCode(CodeProject project, SourceParser parser, IEnumerable <Configuration> configurations)
     : this(project, parser)
 {
     Param.Ignore(project, parser, configurations);
     this.configurations = configurations;
 }
 public AnalyzedSourceCode(CodeProject project, SourceParser parser, string path, string codeToAnalyze)
     : base(project, parser)
 {
     this.path = path;
     this.codeToAnalyze = codeToAnalyze;
 }
예제 #35
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="projectItem">The Visual Studio IDE project item mapping to this file.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser, ProjectItem projectItem)
     : base(path, project, parser, null)
 {
     Param.Ignore(path, project, parser, projectItem);
     this.projectItem = projectItem;
 }
예제 #36
0
        /// <summary>
        /// Saves the given code document results into a cache document.
        /// </summary>
        /// <param name="document">The document to save.</param>
        /// <param name="parser">The parser that created the document.</param>
        /// <param name="settingsTimeStamp">The time when the settings were last updated.</param>
        /// <returns>Returns true if the document was saved.</returns>
        public bool SaveDocumentResults(ICodeDocument document, SourceParser parser, DateTime settingsTimeStamp)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(settingsTimeStamp);

            bool success = false;

            lock (this)
            {
                XmlDocument xml = null;

                try
                {
                    if (!this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                    {
                        XmlNode temp;
                        xml = this.OpenResultsCache(document.SourceCode, parser, out temp);
                        if (xml != null)
                        {
                            this.documentHash.Add(document.SourceCode.Project.Location, xml);
                        }
                    }
                    else
                    {
                        xml = this.documentHash[document.SourceCode.Project.Location];
                    }

                    if (xml != null)
                    {
                        XmlNode remove = xml.DocumentElement.SelectSingleNode(
                            string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", document.SourceCode.Name, parser.Id));
                        if (remove != null)
                        {
                            xml.DocumentElement.RemoveChild(remove);
                        }
                    }
                    else
                    {
                        xml = new XmlDocument();

                        // Create the document node.
                        xml.AppendChild(xml.CreateElement("stylecopresultscache"));

                        // Add the version.
                        XmlNode versionNode = xml.CreateElement("version");
                        xml.DocumentElement.AppendChild(versionNode);
                        versionNode.InnerText = ResultsCache.Version;

                        if (this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                        {
                            this.documentHash.Remove(document.SourceCode.Project.Location);
                        }

                        this.documentHash.Add(document.SourceCode.Project.Location, xml);
                    }

                    XmlNode root = xml.CreateElement("sourcecode");
                    XmlAttribute name = xml.CreateAttribute("name");
                    name.Value = document.SourceCode.Name;
                    root.Attributes.Append(name);
                    xml.DocumentElement.AppendChild(root);

                    // Save the last write time of the settings.
                    XmlNode settingsNode = xml.CreateElement("settings");
                    root.AppendChild(settingsNode);

                    XmlNode node = xml.CreateElement("timestamp");
                    settingsNode.AppendChild(node);
                    node.InnerText = settingsTimeStamp.ToString(CultureInfo.InvariantCulture);

                    node = xml.CreateElement("milliseconds");
                    settingsNode.AppendChild(node);
                    node.InnerText = settingsTimeStamp.Millisecond.ToString(CultureInfo.InvariantCulture);

                    // Get the last write time of the source code.
                    DateTime writeTime = document.SourceCode.TimeStamp;

                    // Add the timestamp.
                    node = xml.CreateElement("timestamp");
                    root.AppendChild(node);
                    node.InnerText = writeTime.ToString(CultureInfo.InvariantCulture);

                    node = xml.CreateElement("milliseconds");
                    root.AppendChild(node);
                    node.InnerText = writeTime.Millisecond.ToString(CultureInfo.InvariantCulture);

                    // Add the parser ID attribute.
                    if (document.SourceCode.Parser != null)
                    {
                        XmlAttribute attribute = xml.CreateAttribute("parser");
                        root.Attributes.Append(attribute);
                        attribute.Value = document.SourceCode.Parser.Id;
                    }

                    // Create the violations node.
                    node = xml.CreateElement("violations");
                    root.AppendChild(node);

                    // Add the violations.
                    SourceParser.ExportViolations(document, xml, node);

                    success = true;
                }
                catch (XmlException)
                {
                }
            }

            return success;
        }
예제 #37
0
        /// <summary>
        /// Sets the parser that this analyzer is attached to.
        /// </summary>
        /// <param name="item">The parser object that this analyzer is attached to.</param>
        internal void SetParser(SourceParser item)
        {
            Param.Ignore(item);

            // Set the reference to the parser object.
            this.parser = item;
        }
예제 #38
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="document">The Visual Studio IDE document mapping to this file.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser, Document document)
     : base(path, project, parser, null)
 {
     Param.Ignore(path, project, parser, document);
     this.document = document;
 }
예제 #39
0
        /// <summary>
        /// Initializes a new instance of the CodeFile class.
        /// </summary>
        /// <param name="path">The path to the code file.</param>
        /// <param name="project">The project that contains this file.</param>
        /// <param name="parser">The parser that created this file object.</param>
        /// <param name="configurations">The list of configurations for the file.</param>
        public CodeFile(string path, CodeProject project, SourceParser parser, IEnumerable<Configuration> configurations)
            : base(project, parser, configurations)
        {
            Param.RequireNotNull(path, "path");
            Param.RequireNotNull(project, "project");
            Param.RequireNotNull(parser, "parser");
            Param.Ignore(configurations);

            this.path = path;

            // If this is not a full path, then we need to add the current directory.
            if (!path.StartsWith(@"\\", StringComparison.Ordinal) && path.Length >= 2 && path[1] != ':')
            {
                // Get the current directory. Remove the trailing slash if it exists.
                string directory = Directory.GetCurrentDirectory();
                if (directory.EndsWith(@"\", StringComparison.Ordinal))
                {
                    directory = directory.Substring(0, directory.Length - 1);
                }

                // Check whether the path starts with a single slash or not.
                if (path.StartsWith(@"\", StringComparison.Ordinal))
                {
                    // Prepend the drive letter.
                    string newPath = directory.Substring(0, 2) + path;
                    path = newPath;
                }
                else
                {
                    // Prepend the current directory.
                    string newPath = directory + @"\" + path;
                    path = newPath;
                }
            }

            // Strip out the name of the file.
            int index = path.LastIndexOf(@"\", StringComparison.Ordinal);
            if (-1 == index)
            {
                this.name = this.path;
            }
            else
            {
                this.name = path.Substring(index + 1, path.Length - index - 1);
                this.folder = path.Substring(0, index);

                if (this.folder != null)
                {
                    // Trim the path and convert it to lowercase characters
                    // so that we can do string matches and find other files and
                    // projects under the same path.
                    this.folder = StyleCopCore.CleanPath(this.folder);
                }
            }

            // Strip out the file extension.
            index = this.name.LastIndexOf(".", StringComparison.Ordinal);
            if (-1 == index)
            {
                this.fileType = string.Empty;
            }
            else
            {
                this.fileType = this.name.Substring(index + 1, this.name.Length - index - 1).ToUpperInvariant();
            }
        }
 /// <summary>
 /// Initializes a new instance of the CodeFile class.
 /// </summary>
 /// <param name="path">
 /// The path to the code file. 
 /// </param>
 /// <param name="project">
 /// The project that contains this file. 
 /// </param>
 /// <param name="parser">
 /// The parser that created this file object. 
 /// </param>
 public CodeFile(string path, CodeProject project, SourceParser parser)
     : this(path, project, parser, null)
 {
     Param.Ignore(path, project, parser);
 }
예제 #41
0
        /// <summary>
        /// Runs the list of analyzers against the given document.
        /// </summary>
        /// <param name="document">
        /// The document to analyze.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="analyzers">
        /// The list of analyzers to run against the document.
        /// </param>
        private void RunAnalyzers(CodeDocument document, SourceParser parser, IEnumerable<SourceAnalyzer> analyzers)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(analyzers, "analyzers");
            StyleCopTrace.In(document, parser, analyzers);

            if (analyzers != null)
            {
                if (parser.SkipAnalysisForDocument(document.SourceCode))
                {
                    string format = string.Format(CultureInfo.CurrentCulture, "Skipping: {0} - {1}", document.SourceCode.Project.Location.SubstringAfterLast('\\'), GetRelativeFileName(document.SourceCode));
                    this.data.Core.SignalOutput(MessageImportance.Normal, format);
                }
                else
                {
                    // Loop through each of the parser's analyzers. 
                    // Only call analyzers that are also in the enabled list.
                    foreach (SourceAnalyzer analyzer in parser.Analyzers)
                    {
                        SourceAnalyzer localAnalyzer = analyzer;
                        if (analyzers.Any(enabledAnalyzers => enabledAnalyzers.Id == localAnalyzer.Id))
                        {
                            // Make sure the user hasn't cancelled us.
                            if (this.data.Core.Cancel)
                            {
                                break;
                            }

                            SourceParser.ClearAnalyzerTags(document);
                            try
                            {
                                if (analyzer.DoAnalysis(document))
                                {
                                    analyzer.AnalyzeDocument(document);
                                }
                            }
                            catch (Exception ex)
                            {
                                StringBuilder details = new StringBuilder();
                                details.AppendLine(string.Format(CultureInfo.CurrentCulture, "Exception thrown by analyzer '{0}' while processing '{1}'.", analyzer.Name, document.SourceCode.Path));

                                // Add exception message for help on bugfix.
                                if (!string.IsNullOrEmpty(ex.Message))
                                {
                                    details.AppendLine(string.Format(CultureInfo.CurrentCulture, "Exception message : {0}"));
                                }

                                this.data.Core.SignalOutput(MessageImportance.High, details.ToString());
                                throw;
                            }
                        }
                    }
                }
            }

            StyleCopTrace.Out();
        }
예제 #42
0
        /// <summary>
        /// Runs the analyzers against the given document.
        /// </summary>
        /// <param name="document">
        /// The document to analyze.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="analyzers">
        /// The analyzers to run against the document.
        /// </param>
        /// <param name="passNumber">
        /// The current pass number.
        /// </param>
        /// <returns>
        /// Returns true if analysis was run, or false if analysis was delayed until the next pass.
        /// </returns>
        private bool TestAndRunAnalyzers(CodeDocument document, SourceParser parser, IEnumerable<SourceAnalyzer> analyzers, int passNumber)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(analyzers);
            Param.Ignore(passNumber);
            StyleCopTrace.In(document, parser, analyzers, passNumber);

            if (analyzers == null)
            {
                return StyleCopTrace.Out(true);
            }

            // Determine whether any of the analyzers wish to delay analysis until the next pass.
            bool delay = false;
            foreach (SourceAnalyzer analyzer in analyzers)
            {
                if (analyzer.DelayAnalysis(document, passNumber))
                {
                    delay = true;
                    break;
                }
            }

            if (!delay)
            {
                this.RunAnalyzers(document, parser, analyzers);
            }

            return StyleCopTrace.Out(!delay);
        }
예제 #43
0
 /// <summary>
 /// Invoked when a new parser is loaded.
 /// </summary>
 /// <param name="parser">
 /// The new parser.
 /// </param>
 public abstract void AddParser(SourceParser parser);
 private SourceCode SourceCodeFactory(string path, CodeProject project, SourceParser parser, object context)
 {
     string codeToAnalyze = context.ToString();
     return new AnalyzedSourceCode(project, parser, path, codeToAnalyze);
 }
예제 #45
0
        /// <summary>
        /// Saves the given code document results into a cache document.
        /// </summary>
        /// <param name="document">The document to save.</param>
        /// <param name="parser">The parser that created the document.</param>
        /// <param name="settingsTimeStamp">The time when the settings were last updated.</param>
        /// <returns>Returns true if the document was saved.</returns>
        public bool SaveDocumentResults(ICodeDocument document, SourceParser parser, DateTime settingsTimeStamp)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(settingsTimeStamp);

            bool success = false;

            lock (this)
            {
                XmlDocument xml = null;

                try
                {
                    if (!this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                    {
                        XmlNode temp;
                        xml = this.OpenResultsCache(document.SourceCode, parser, out temp);
                        if (xml != null)
                        {
                            this.documentHash.Add(document.SourceCode.Project.Location, xml);
                        }
                    }
                    else
                    {
                        xml = this.documentHash[document.SourceCode.Project.Location];
                    }

                    if (xml != null)
                    {
                        XmlNode remove = xml.DocumentElement.SelectSingleNode(
                            string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", document.SourceCode.Name, parser.Id));
                        if (remove != null)
                        {
                            xml.DocumentElement.RemoveChild(remove);
                        }
                    }
                    else
                    {
                        xml = new XmlDocument();

                        // Create the document node.
                        xml.AppendChild(xml.CreateElement("stylecopresultscache"));

                        // Add the version.
                        XmlNode versionNode = xml.CreateElement("version");
                        xml.DocumentElement.AppendChild(versionNode);
                        versionNode.InnerText = ResultsCache.Version;

                        if (this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                        {
                            this.documentHash.Remove(document.SourceCode.Project.Location);
                        }

                        this.documentHash.Add(document.SourceCode.Project.Location, xml);
                    }

                    XmlNode      root = xml.CreateElement("sourcecode");
                    XmlAttribute name = xml.CreateAttribute("name");
                    name.Value = document.SourceCode.Name;
                    root.Attributes.Append(name);
                    xml.DocumentElement.AppendChild(root);

                    // Save the last write time of the settings.
                    XmlNode settingsNode = xml.CreateElement("settings");
                    root.AppendChild(settingsNode);

                    XmlNode node = xml.CreateElement("timestamp");
                    settingsNode.AppendChild(node);
                    node.InnerText = settingsTimeStamp.ToString(CultureInfo.InvariantCulture);

                    node = xml.CreateElement("milliseconds");
                    settingsNode.AppendChild(node);
                    node.InnerText = settingsTimeStamp.Millisecond.ToString(CultureInfo.InvariantCulture);

                    // Get the last write time of the source code.
                    DateTime writeTime = document.SourceCode.TimeStamp;

                    // Add the timestamp.
                    node = xml.CreateElement("timestamp");
                    root.AppendChild(node);
                    node.InnerText = writeTime.ToString(CultureInfo.InvariantCulture);

                    node = xml.CreateElement("milliseconds");
                    root.AppendChild(node);
                    node.InnerText = writeTime.Millisecond.ToString(CultureInfo.InvariantCulture);

                    // Add the parser ID attribute.
                    if (document.SourceCode.Parser != null)
                    {
                        XmlAttribute attribute = xml.CreateAttribute("parser");
                        root.Attributes.Append(attribute);
                        attribute.Value = document.SourceCode.Parser.Id;
                    }

                    // Create the violations node.
                    node = xml.CreateElement("violations");
                    root.AppendChild(node);

                    // Add the violations.
                    SourceParser.ExportViolations(document, xml, node);

                    success = true;
                }
                catch (XmlException)
                {
                }
            }

            return(success);
        }
 /// <summary>
 /// Invoked when a new parser is loaded.
 /// </summary>
 /// <param name="parser">
 /// The new parser.
 /// </param>
 public abstract void AddParser(SourceParser parser);
예제 #47
0
        /// <summary>
        /// Saves the given code document results into a cache document.
        /// </summary>
        /// <param name="document">
        /// The document to save.
        /// </param>
        /// <param name="parser">
        /// The parser that created the document.
        /// </param>
        /// <param name="settingsTimeStamp">
        /// The time when the settings were last updated.
        /// </param>
        /// <returns>
        /// Returns true if the document was saved.
        /// </returns>
        public bool SaveDocumentResults(CodeDocument document, SourceParser parser, DateTime settingsTimeStamp)
        {
            Param.AssertNotNull(document, "document");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(settingsTimeStamp);

            bool success = false;

            lock (this)
            {
                try
                {
                    XmlDocument xml;
                    if (!this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                    {
                        XmlNode temp;
                        xml = this.OpenResultsCache(document.SourceCode, parser, out temp);
                        if (xml != null)
                        {
                            this.documentHash.Add(document.SourceCode.Project.Location, xml);
                        }
                    }
                    else
                    {
                        xml = this.documentHash[document.SourceCode.Project.Location];
                    }

                    if (xml != null)
                    {
                        XmlNode remove =
                            xml.DocumentElement.SelectSingleNode(
                                string.Format(CultureInfo.InvariantCulture, "sourcecode[@name=\"{0}\"][@parser=\"{1}\"]", document.SourceCode.Name, parser.Id));
                        if (remove != null)
                        {
                            xml.DocumentElement.RemoveChild(remove);
                        }
                    }
                    else
                    {
                        xml = new XmlDocument();

                        // Create the document node.
                        xml.AppendChild(xml.CreateElement("stylecopresultscache"));

                        // Add the version.
                        XmlNode versionNode = xml.CreateElement("version");
                        xml.DocumentElement.AppendChild(versionNode);
                        versionNode.InnerText = ResultsCache.Version;

                        if (this.documentHash.ContainsKey(document.SourceCode.Project.Location))
                        {
                            this.documentHash.Remove(document.SourceCode.Project.Location);
                        }

                        this.documentHash.Add(document.SourceCode.Project.Location, xml);
                    }

                    XmlNode root = xml.CreateElement("sourcecode");
                    XmlAttribute name = xml.CreateAttribute("name");
                    name.Value = document.SourceCode.Name;
                    root.Attributes.Append(name);
                    xml.DocumentElement.AppendChild(root);

                    // Create the timestamps node.
                    // We need to store the timestamp of all files that were used to create the violation.
                    // Parser, Rules, settings, source file, spell checker, and dictionaries.
                    XmlElement node = xml.CreateElement("timestamps");
                    root.AppendChild(node);

                    this.AddTimestampToXml(xml, node, "styleCop", this.core.TimeStamp);

                    this.AddTimestampToXml(xml, node, "settingsFile", settingsTimeStamp);

                    // Stores the last write time of the source code.
                    this.AddTimestampToXml(xml, node, "sourceFile", document.SourceCode.TimeStamp);

                    // Store all the rules and parser timestamps
                    this.AddTimestampToXml(xml, node, "parser", document.SourceCode.Parser.TimeStamp);

                    foreach (SourceAnalyzer analyzer in document.SourceCode.Parser.Analyzers)
                    {
                        this.AddTimestampToXml(xml, node, analyzer.Id, analyzer.TimeStamp);
                        this.AddHashCodeToXml(xml, node, analyzer.Id + ".FilesHashCode", analyzer.GetDependantFilesHashCode(document.SourceCode.Project.Culture));
                    }

                    // Add the parser ID attribute.
                    if (document.SourceCode.Parser != null)
                    {
                        XmlAttribute attribute = xml.CreateAttribute("parser");
                        root.Attributes.Append(attribute);
                        attribute.Value = document.SourceCode.Parser.Id;
                    }

                    // Create the violations node.
                    node = xml.CreateElement("violations");
                    root.AppendChild(node);

                    // Add the violations.
                    SourceParser.ExportViolations(document, xml, node);

                    success = true;
                }
                catch (XmlException)
                {
                }
            }

            return success;
        }
예제 #48
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="document">The Visual Studio IDE document mapping to this file.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser, Document document)
     : base(path, project, parser, null)
 {
     Param.Ignore(path, project, parser, document);
     this.document = document;
 }
예제 #49
0
        /// <summary>
        /// Loads results for the given source code document from the cache.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code to load.
        /// </param>
        /// <param name="parser">
        /// The parser that created this document.
        /// </param>
        /// <param name="writeTime">
        /// The last write time of the document.
        /// </param>
        /// <param name="settingsTimestamp">
        /// The time when the settings were last updated.
        /// </param>
        /// <returns>
        /// Returns true if the results were loaded from the cache.
        /// </returns>
        public bool LoadResults(SourceCode sourceCode, SourceParser parser, DateTime writeTime, DateTime settingsTimestamp)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parser, "parser");
            Param.Ignore(writeTime);
            Param.Ignore(settingsTimestamp);

            lock (this)
            {
                XmlNode     item = null;
                XmlDocument doc  = this.OpenResultsCache(sourceCode, parser, out item);

                if (doc != null && item != null)
                {
                    if (!this.documentHash.ContainsKey(sourceCode.Project.Location))
                    {
                        this.documentHash.Add(sourceCode.Project.Location, doc);
                    }

                    try
                    {
                        // Check the timestamps of all the files.
                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/styleCop"), this.core.TimeStamp))
                        {
                            return(false);
                        }

                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/settingsFile"), settingsTimestamp))
                        {
                            return(false);
                        }

                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/sourceFile"), writeTime))
                        {
                            return(false);
                        }

                        if (!IsNodeUpToDate(item.SelectSingleNode("timestamps/parser"), parser.TimeStamp))
                        {
                            return(false);
                        }

                        foreach (SourceAnalyzer analyzer in parser.Analyzers)
                        {
                            if (!IsNodeUpToDate(item.SelectSingleNode(string.Concat("timestamps/", analyzer.Id)), analyzer.TimeStamp))
                            {
                                return(false);
                            }

                            if (
                                !IsNodeUpToDate(
                                    item.SelectSingleNode(string.Concat("timestamps/", analyzer.Id + ".FilesHashCode")),
                                    analyzer.GetDependantFilesHashCode(sourceCode.Project.Culture)))
                            {
                                return(false);
                            }
                        }

                        XmlNode violations = item.SelectSingleNode("violations");
                        if (violations != null)
                        {
                            if (parser.ImportViolations(sourceCode, violations))
                            {
                                return(true);
                            }
                        }
                    }
                    catch (XmlException)
                    {
                    }
                }
            }

            return(false);
        }
예제 #50
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="projectItem">The Visual Studio IDE project item mapping to this file.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser, ProjectItem projectItem)
     : base(path, project, parser, null)
 {
     Param.Ignore(path, project, parser, projectItem);
     this.projectItem = projectItem;
 }
예제 #51
0
 public CodeText(string text, CodeProject project, SourceParser parser)
     : this(text, project, parser, null)
 {
     Param.Ignore(text, project, parser);
 }
 public AnalyzedSourceCode(CodeProject project, SourceParser parser, IEnumerable<Configuration> configurations, string path, string codeToAnalyze)
     : base(project, parser, configurations)
 {
     this.path = path;
     this.codeToAnalyze = codeToAnalyze;
 }
예제 #53
0
        /// <summary>
        /// Initializes a new instance of the CodeFile class.
        /// </summary>
        /// <param name="path">The path to the code file.</param>
        /// <param name="project">The project that contains this file.</param>
        /// <param name="parser">The parser that created this file object.</param>
        /// <param name="configurations">The list of configurations for the file.</param>
        public CodeFile(string path, CodeProject project, SourceParser parser, IEnumerable <Configuration> configurations)
            : base(project, parser, configurations)
        {
            Param.RequireNotNull(path, "path");
            Param.RequireNotNull(project, "project");
            Param.RequireNotNull(parser, "parser");
            Param.Ignore(configurations);

            this.path = path;

            // If this is not a full path, then we need to add the current directory.
            if (!path.StartsWith(@"\\", StringComparison.Ordinal) && path.Length >= 2 && path[1] != ':')
            {
                // Get the current directory. Remove the trailing slash if it exists.
                string directory = Directory.GetCurrentDirectory();
                if (directory.EndsWith(@"\", StringComparison.Ordinal))
                {
                    directory = directory.Substring(0, directory.Length - 1);
                }

                // Check whether the path starts with a single slash or not.
                if (path.StartsWith(@"\", StringComparison.Ordinal))
                {
                    // Prepend the drive letter.
                    string newPath = directory.Substring(0, 2) + path;
                    path = newPath;
                }
                else
                {
                    // Prepend the current directory.
                    string newPath = directory + @"\" + path;
                    path = newPath;
                }
            }

            // Strip out the name of the file.
            int index = path.LastIndexOf(@"\", StringComparison.Ordinal);

            if (-1 == index)
            {
                this.name = this.path;
            }
            else
            {
                this.name   = path.Substring(index + 1, path.Length - index - 1);
                this.folder = path.Substring(0, index);

                if (this.folder != null)
                {
                    // Trim the path and convert it to lowercase characters
                    // so that we can do string matches and find other files and
                    // projects under the same path.
                    this.folder = StyleCopCore.CleanPath(this.folder);
                }
            }

            // Strip out the file extension.
            index = this.name.LastIndexOf(".", StringComparison.Ordinal);
            if (-1 == index)
            {
                this.fileType = string.Empty;
            }
            else
            {
                this.fileType = this.name.Substring(index + 1, this.name.Length - index - 1).ToUpperInvariant();
            }
        }
        /// <summary>
        /// Initializes a new instance of the CodeFile class.
        /// </summary>
        /// <param name="path">
        /// The path to the code file. 
        /// </param>
        /// <param name="project">
        /// The project that contains this file. 
        /// </param>
        /// <param name="parser">
        /// The parser that created this file object. 
        /// </param>
        /// <param name="configurations">
        /// The list of configurations for the file. 
        /// </param>
        public CodeFile(string path, CodeProject project, SourceParser parser, IEnumerable<Configuration> configurations)
            : base(project, parser, configurations)
        {
            Param.RequireNotNull(path, "path");
            Param.RequireNotNull(project, "project");
            Param.RequireNotNull(parser, "parser");
            Param.Ignore(configurations);

            // If this is not a full path, then we need to add the current directory.
            if (!path.StartsWith(@"\\", StringComparison.Ordinal) && path.Length >= 2 && path[1] != ':')
            {
                path = System.IO.Path.GetFullPath(path);
            }

            // BugFix 6777 - Update the path field after correcting the local path variable
            this.path = path;
            this.name = System.IO.Path.GetFileName(path);
            this.folder = StyleCopCore.CleanPath(System.IO.Path.GetDirectoryName(path));

            // Strip out the file extension.
            this.fileType = System.IO.Path.GetExtension(this.name).ToUpperInvariant();
            if (this.fileType.Length > 0)
            {
                this.fileType = this.fileType.Substring(1);
            }
        }
예제 #55
0
 /// <summary>
 /// Creates a new <see cref="CodeFile"/> instance with the given values.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="context">Optional context information.</param>
 /// <returns>Returns the newly created <see cref="CodeFile"/>.</returns>
 protected virtual CodeFile CreateCodeFile(string path, CodeProject project, SourceParser parser, object context)
 {
     Param.Ignore(path, project, parser, context);
     return(new CodeFile(path, project, parser));
 }
예제 #56
0
 /// <summary>
 /// Initializes a new instance of the SourceCode class.
 /// </summary>
 /// <param name="project">
 /// The project that contains this document.
 /// </param>
 /// <param name="parser">
 /// The parser that created this document.
 /// </param>
 /// <param name="configurations">
 /// The list of configurations for the document.
 /// </param>
 protected SourceCode(CodeProject project, SourceParser parser, IEnumerable<Configuration> configurations)
     : this(project, parser)
 {
     Param.Ignore(project, parser, configurations);
     this.configurations = configurations;
 }
예제 #57
0
 /// <summary>
 /// Creates a new <see cref="CodeFile"/> instance with the given values.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 /// <param name="context">Optional context information.</param>
 /// <returns>Returns the newly created <see cref="CodeFile"/>.</returns>
 protected virtual CodeFile CreateCodeFile(string path, CodeProject project, SourceParser parser, object context)
 {
     Param.Ignore(path, project, parser, context);
     return new CodeFile(path, project, parser);
 }
예제 #58
0
 /// <summary>
 /// Initializes a new instance of the VisualStudioCodeFile class.
 /// </summary>
 /// <param name="path">The path to the code file.</param>
 /// <param name="project">The project that contains this file.</param>
 /// <param name="parser">The parser that created this file object.</param>
 internal VisualStudioCodeFile(string path, CodeProject project, SourceParser parser)
     : base(path, project, parser, null)
 {
     Param.Ignore(path, project, parser);
 }