/// <summary>
        /// Initializes a new instance of the SyntaxException class.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code document containing the exception.
        /// </param>
        /// <param name="lineNumber">
        /// The line number of the exception.
        /// </param>
        public SyntaxException(SourceCode sourceCode, int lineNumber)
            : base(string.Format(CultureInfo.CurrentCulture, Strings.SyntaxErrorInFile, sourceCode.Path, lineNumber))
        {
            Param.RequireNotNull(sourceCode, "sourceCode");
            Param.RequireGreaterThanZero(lineNumber, "lineNumber");

            this.sourceCode = sourceCode;
            this.lineNumber = lineNumber;
        }
        /// <summary>
        /// Initializes a new instance of the SyntaxException class.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code document containing the exception.
        /// </param>
        /// <param name="lineNumber">
        /// The line number of the exception.
        /// </param>
        /// <param name="innerException">
        /// The exception within this exception.
        /// </param>
        public SyntaxException(SourceCode sourceCode, int lineNumber, Exception innerException)
            : base(string.Format(CultureInfo.CurrentCulture, Strings.SyntaxErrorInFile, sourceCode.Path, lineNumber), innerException)
        {
            Param.RequireNotNull(sourceCode, "sourceCode");
            Param.RequireGreaterThanZero(lineNumber, "lineNumber");
            Param.Ignore(innerException);

            this.sourceCode = sourceCode;
            this.lineNumber = lineNumber;
        }
        /// <summary>
        /// Initializes a new instance of the SyntaxException class.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code document containing the exception.
        /// </param>
        /// <param name="lineNumber">
        /// The line number of the exception.
        /// </param>
        /// <param name="message">
        /// The exception message.
        /// </param>
        public SyntaxException(SourceCode sourceCode, int lineNumber, string message)
            : base(string.Format(CultureInfo.CurrentCulture, Strings.SyntaxErrorInFileWithMessage, sourceCode.Path, lineNumber, message))
        {
            Param.RequireNotNull(sourceCode, "sourceCode");
            Param.RequireGreaterThanZero(lineNumber, "lineNumber");
            Param.RequireValidString(message, "message");

            this.sourceCode = sourceCode;
            this.lineNumber = lineNumber;
        }
Beispiel #4
0
        /// <summary>
        /// Disposes the contents of the class.
        /// </summary>
        /// <param name="disposing">
        /// Indicates whether to dispose unmanaged resources.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            Param.Ignore(disposing);

            if (disposing)
            {
                this.sourceCode   = null;
                this.analyzerData = null;
            }
        }
Beispiel #5
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);
        }
Beispiel #6
0
        /// <summary>
        /// Adds the given source code document to the project.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code to add.
        /// </param>
        internal virtual void AddSourceCode(SourceCode sourceCode)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");

            if (string.IsNullOrEmpty(sourceCode.Type))
            {
                throw new ArgumentException(Strings.SourceCodeTypePropertyNotSet);
            }

            this.sourceCodes.Add(sourceCode);
        }
Beispiel #7
0
        /// <summary>
        /// Initializes a new instance of the Violation class.
        /// </summary>
        /// <param name="rule">The rule that triggered the violation.</param>
        /// <param name="sourceCode">The source code that this violation appears in.</param>
        /// <param name="line">The line in the source code where the violation occurs.</param>
        /// <param name="message">The context message for the violation.</param>
        internal Violation(Rule rule, SourceCode sourceCode, int line, string message)
        {
            Param.AssertNotNull(rule, "rule");
            Param.Ignore(sourceCode);
            Param.AssertGreaterThanOrEqualToZero(line, "line");
            Param.AssertNotNull(message, "message");

            this.rule = rule;
            this.sourceCode = sourceCode;
            this.line = line;
            this.message = message;
        }
Beispiel #8
0
        /// <summary>
        /// Initializes a new instance of the Violation class.
        /// </summary>
        /// <param name="rule">The rule that triggered the violation.</param>
        /// <param name="sourceCode">The source code that this violation appears in.</param>
        /// <param name="line">The line in the source code where the violation occurs.</param>
        /// <param name="message">The context message for the violation.</param>
        internal Violation(Rule rule, SourceCode sourceCode, int line, string message)
        {
            Param.AssertNotNull(rule, "rule");
            Param.Ignore(sourceCode);
            Param.AssertGreaterThanOrEqualToZero(line, "line");
            Param.AssertNotNull(message, "message");

            this.rule       = rule;
            this.sourceCode = sourceCode;
            this.line       = line;
            this.message    = message;
        }
Beispiel #9
0
        /// <summary>
        /// Returns the leafname of the source code path.
        /// </summary>
        /// <param name="sourceCode">
        /// The SourceCode object to use.
        /// </param>
        /// <returns>
        /// The leafname.
        /// </returns>
        private static string GetRelativeFileName(SourceCode sourceCode)
        {
            string sourceCodePath            = sourceCode.Path;
            string sourceCodeProjectLocation = sourceCode.Project.Location;
            string outputText = sourceCode.Name;

            if (sourceCodePath != null && sourceCodeProjectLocation != null && sourceCodePath.StartsWith(sourceCodeProjectLocation, true, CultureInfo.InvariantCulture))
            {
                outputText = sourceCodePath.SubstringAfter(sourceCodeProjectLocation, StringComparison.InvariantCultureIgnoreCase);
            }

            return(outputText);
        }
Beispiel #10
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;
        }
Beispiel #11
0
        /// <summary>
        /// Adds one violation to the given source code document.
        /// </summary>
        /// <param name="sourceCode">The source code document that the violation appears in.</param>
        /// <param name="line">The line in the code where the violation occurs.</param>
        /// <param name="ruleName">The name of the rule that triggered the violation.</param>
        /// <param name="values">String parameters to insert into the violation string.</param>
        public void AddViolation(SourceCode sourceCode, int line, string ruleName, params object[] values)
        {
            Param.Ignore(sourceCode, line, ruleName, values);

            Rule rule = this.GetRule(ruleName);

            if (rule == null)
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.RuleDoesNotExist, ruleName), "ruleName");
            }

            // Look up this violation type.
            this.Core.AddViolation(sourceCode, rule, line, values);
        }
Beispiel #12
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);
        }
Beispiel #13
0
            /// <summary>
            /// Gets the analysis status for the given source code document.
            /// </summary>
            /// <param name="sourceCode">The source code to retrieve status for.</param>
            /// <returns>Returns the analysis status for the source code.</returns>
            public DocumentAnalysisStatus GetDocumentStatus(SourceCode sourceCode)
            {
                Param.AssertNotNull(sourceCode, "sourceCode");

                DocumentAnalysisStatus status;

                if (!this.sourceCodeInstanceStatus.TryGetValue(sourceCode, out status))
                {
                    // Create a new status object and add add it to the dictionary.
                    status = new DocumentAnalysisStatus();
                    this.sourceCodeInstanceStatus.Add(sourceCode, status);
                }

                return(status);
            }
Beispiel #14
0
            /// <summary>
            /// Gets the next source code document to analyze.
            /// </summary>
            /// <returns>Returns the source code document to analyze or null if none.</returns>
            public SourceCode GetNextSourceCodeDocument()
            {
                // Keep looping until we find a file that is not marked as excluded.
                while (true)
                {
                    SourceCode sourceCode = this.ExtractNextSourceCodeDocument();
                    if (sourceCode == null)
                    {
                        return(null);
                    }

                    sourceCode.Settings = sourceCode.Project.Settings.GetCustomSettingsForFile(sourceCode.Name);

                    return(sourceCode);
                }
            }
Beispiel #15
0
        /// <summary>
        /// Initializes a new instance of the Violation class.
        /// </summary>
        /// <param name="rule">The rule that triggered the violation.</param>
        /// <param name="element">The element that this violation appears in.</param>
        /// <param name="line">The line in the source code where the violation occurs.</param>
        /// <param name="message">The context message for the violation.</param>
        internal Violation(Rule rule, ICodeElement element, int line, string message)
        {
            Param.AssertNotNull(rule, "rule");
            Param.Ignore(element);
            Param.AssertGreaterThanOrEqualToZero(line, "line");
            Param.AssertNotNull(message, "message");

            this.rule    = rule;
            this.element = element;
            this.line    = line;
            this.message = message;

            if (this.element != null && this.element.Document != null)
            {
                this.sourceCode = this.element.Document.SourceCode;
            }
        }
Beispiel #16
0
        /// <summary>
        /// Initializes a new instance of the Violation class.
        /// </summary>
        /// <param name="rule">The rule that triggered the violation.</param>
        /// <param name="element">The element that this violation appears in.</param>
        /// <param name="line">The line in the source code where the violation occurs.</param>
        /// <param name="message">The context message for the violation.</param>
        internal Violation(Rule rule, ICodeElement element, int line, string message)
        {
            Param.AssertNotNull(rule, "rule");
            Param.Ignore(element);
            Param.AssertGreaterThanOrEqualToZero(line, "line");
            Param.AssertNotNull(message, "message");

            this.rule = rule;
            this.element = element;
            this.line = line;
            this.message = message;

            if (this.element != null && this.element.Document != null)
            {
                this.sourceCode = this.element.Document.SourceCode;
            }
        }
Beispiel #17
0
            /// <summary>
            /// Pulls out the next source code document.
            /// </summary>
            /// <returns>Returns the source code document to analyze or null if none.</returns>
            private SourceCode ExtractNextSourceCodeDocument()
            {
                SourceCode sourceCode = null;

                while (this.projectIndex < this.projects.Count)
                {
                    CodeProject project = this.projects[this.projectIndex];

                    ++this.sourceCodeInstanceIndex;
                    if (this.sourceCodeInstanceIndex >= project.SourceCodeInstances.Count)
                    {
                        ++this.projectIndex;
                        this.sourceCodeInstanceIndex = -1;
                    }
                    else
                    {
                        sourceCode = project.SourceCodeInstances[this.sourceCodeInstanceIndex];
                        break;
                    }
                }

                return(sourceCode);
            }
Beispiel #18
0
        /// <summary>
        /// Initializes a new instance of the Violation class.
        /// </summary>
        /// <param name="rule">
        /// The rule that triggered the violation.
        /// </param>
        /// <param name="element">
        /// The element that this violation appears in.
        /// </param>
        /// <param name="line">
        /// The line in the source code where the violation occurs.
        /// </param>
        /// <param name="message">
        /// The context message for the violation.
        /// </param>
        internal Violation(Rule rule, ICodeElement element, int line, string message)
        {
            Param.AssertNotNull(rule, "rule");
            Param.Ignore(element);
            Param.AssertGreaterThanOrEqualToZero(line, "line");
            Param.AssertNotNull(message, "message");

            this.rule    = rule;
            this.element = element;
            this.line    = line;

            // As the line only is passed in we ensure the location is null.
            // A null location indicates we only know the line it was on.
            this.location = null;
            this.message  = message;

            if (this.element != null && this.element.Document != null)
            {
                this.sourceCode = this.element.Document.SourceCode;
            }

            this.UpdateKey();
        }
Beispiel #19
0
        /// <summary>
        /// Saves the fixed document back to the source location.
        /// </summary>
        /// <param name="sourceCode">The source code representing the source of the document.</param>
        /// <param name="document">The document to save to the source code location.</param>
        private void SaveDocumentToSource(SourceCode sourceCode, ICodeDocument document)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(document, "document");

            Exception exception;

            if (!sourceCode.Write(document, out exception))
            {
                if (exception != null)
                {
                    this.data.Core.CoreViolations.AddViolation(null, 1, Rules.SaveExceptionOccurred, exception.GetType(), sourceCode.Path, exception.Message);
                }
                else
                {
                    this.data.Core.CoreViolations.AddViolation(null, 1, Rules.UnknownSaveExceptionOccurred, sourceCode.Path);
                }
            }
            else
            {
                document.Dirty = false;
            }
        }
        /// <summary>
        /// Adds a source code document to the given project.
        /// </summary>
        /// <param name="project">
        /// The project which should contain the source code instance.
        /// </param>
        /// <param name="path">
        /// The path to the source code document to add.
        /// </param>
        /// <param name="context">
        /// Optional context information.
        /// </param>
        /// <returns>
        /// Returns true if any source code documents were added to the project.
        /// </returns>
        public override bool AddSourceCode(CodeProject project, string path, object context)
        {
            Param.RequireNotNull(project, "project");
            Param.RequireValidString(path, "path");
            Param.Ignore(context);

            bool added = false;

            // Get the parsers for this file based on its extension.
            string extension = Path.GetExtension(path);

            if (extension != null && extension.Length > 0)
            {
                // Remove the leading dot and convert the extension to lower-case.
                extension = extension.Substring(1).ToUpperInvariant();

                ICollection <SourceParser> parserList = this.GetParsersForFileType(extension);
                if (parserList != null)
                {
                    // Create SourceCode objects representing this file, for each parser.
                    foreach (SourceParser parser in parserList)
                    {
                        // Create and return a SourceCode for this file.
                        SourceCode source = this.sourceCodeFactory(path, project, parser, context);
                        if (source == null)
                        {
                            throw new InvalidOperationException(Strings.SourceCodeFactoryReturnsNull);
                        }

                        project.AddSourceCode(source);
                        added = true;
                    }
                }
            }

            return(added);
        }
Beispiel #21
0
        /// <summary>
        /// Adds one violation to the given source code document.
        /// </summary>
        /// <param name="sourceCode">The source code document that the violation appears in.</param>
        /// <param name="line">The line in the code where the violation occurs.</param>
        /// <param name="ruleName">The name of the rule that triggered the violation.</param>
        /// <param name="values">String parameters to insert into the violation string.</param>
        public void AddViolation(SourceCode sourceCode, int line, string ruleName, params object[] values)
        {
            Param.Ignore(sourceCode, line, ruleName, values);

            Rule rule = this.GetRule(ruleName);
            if (rule == null)
            {
                throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, Strings.RuleDoesNotExist, ruleName), "ruleName");
            }

            // Look up this violation type.
            this.Core.AddViolation(sourceCode, rule, line, values);
        }
Beispiel #22
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);
        }
Beispiel #23
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;
        }
Beispiel #24
0
        /// <summary>
        /// Adds a generic violation.
        /// </summary>
        /// <param name="sourceCode">The file to add the violation to.</param>
        /// <param name="violation">The violation to add to the element.</param>
        internal void AddViolation(SourceCode sourceCode, Violation violation)
        {
            Param.Ignore(sourceCode, "sourceCode");
            Param.AssertNotNull(violation, "violation");

            bool signal = true;

            // Add the violation to the file.
            if (sourceCode != null)
            {
                if (!sourceCode.AddViolation(violation))
                {
                    signal = false;
                }
            }

            // Signal that there is a new violation.
            if (signal)
            {
                this.OnViolationEncountered(new ViolationEventArgs(violation));
            }
        }
            /// <summary>
            /// Gets the analysis status for the given source code document.
            /// </summary>
            /// <param name="sourceCode">The source code to retrieve status for.</param>
            /// <returns>Returns the analysis status for the source code.</returns>
            public DocumentAnalysisStatus GetDocumentStatus(SourceCode sourceCode)
            {
                Param.AssertNotNull(sourceCode, "sourceCode");

                DocumentAnalysisStatus status;
                if (!this.sourceCodeInstanceStatus.TryGetValue(sourceCode, out status))
                {
                    // Create a new status object and add add it to the dictionary.
                    status = new DocumentAnalysisStatus();
                    this.sourceCodeInstanceStatus.Add(sourceCode, status);
                }

                return status;
            }
Beispiel #26
0
 /// <summary>
 /// Initializes a new instance of the CodeDocument class.
 /// </summary>
 /// <param name="sourceCode">
 /// The source code document this instance represents.
 /// </param>
 protected CodeDocument(SourceCode sourceCode)
 {
     Param.RequireNotNull(sourceCode, "sourceCode");
     this.sourceCode = sourceCode;
 }
        /// <summary>
        /// Initializes a new instance of the SyntaxException class.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code document containing the exception.
        /// </param>
        /// <param name="lineNumber">
        /// The line number of the exception.
        /// </param>
        /// <param name="message">
        /// The exception message.
        /// </param>
        /// <param name="innerException">
        /// The exception within this exception.
        /// </param>
        public SyntaxException(SourceCode sourceCode, int lineNumber, string message, Exception innerException)
            : base(string.Format(CultureInfo.CurrentCulture, Strings.SyntaxErrorInFileWithMessage, sourceCode.Path, lineNumber, message), innerException)
        {
            Param.RequireNotNull(sourceCode, "sourceCode");
            Param.RequireGreaterThanZero(lineNumber, "lineNumber");
            Param.RequireValidString(message, "message");
            Param.Ignore(innerException);

            this.sourceCode = sourceCode;
            this.lineNumber = lineNumber;
        }
Beispiel #28
0
        /// <summary>
        /// Adds one violation to the given source code document.
        /// </summary>
        /// <param name="sourceCode">The source code document that the violation appears in.</param>
        /// <param name="line">The line in the code where the violation occurs.</param>
        /// <param name="ruleName">The name of the rule that triggered the violation.</param>
        /// <param name="values">String parameters to insert into the violation string.</param>
        public void AddViolation(SourceCode sourceCode, int line, Enum ruleName, params object[] values)
        {
            Param.Ignore(sourceCode);
            Param.Ignore(line);
            Param.RequireNotNull(ruleName, "ruleName");
            Param.Ignore(values);

            this.AddViolation(sourceCode, line, ruleName.ToString(), values);
        }
Beispiel #29
0
        /// <summary>
        /// Imports the cached violations under the given node.
        /// </summary>
        /// <param name="sourceCode">The source code containing the violations.</param>
        /// <param name="parentNode">The parent xml node containing the list of violations.</param>
        /// <returns>Returns true if all the data was loaded successfully from the file.</returns>
        internal bool ImportViolations(SourceCode sourceCode, XmlNode parentNode)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parentNode, "parentNode");

            bool success = true;

            try
            {
                XmlNodeList violations = parentNode.SelectNodes("violation");
                if (violations != null && violations.Count > 0)
                {
                    foreach (XmlNode violationNode in violations)
                    {
                        // Get the violation data from the xml node.
                        XmlNode nameSpace = violationNode.SelectSingleNode("@namespace");
                        XmlNode ruleName = violationNode.SelectSingleNode("@rule");
                        XmlNode ruleCheckId = violationNode.SelectSingleNode("@ruleCheckId");
                        XmlNode context = violationNode.SelectSingleNode("context");
                        XmlNode lineNumber = violationNode.SelectSingleNode("line");
                        XmlNode warning = violationNode.SelectSingleNode("warning");

                        // Create a Rule object representing this data.
                        Rule rule = new Rule(
                            ruleName.InnerText,
                            nameSpace.InnerText,
                            ruleCheckId.InnerText,
                            context.InnerText,
                            Convert.ToBoolean(warning.InnerText, CultureInfo.InvariantCulture));

                        // Create a Violation object representing this data.
                        Violation violation = new Violation(
                            rule,
                            sourceCode,
                            Convert.ToInt32(lineNumber.InnerText, null),
                            context.InnerText);

                        this.AddViolation(violation);
                    }
                }
            }
            catch (ArgumentException)
            {
                success = false;
            }
            catch (XmlException)
            {
                success = false;
            }
            catch (FormatException)
            {
                success = false;
            }
            catch (OverflowException)
            {
                success = false;
            }

            return success;
        }
Beispiel #30
0
 /// <summary>
 /// Indicates whether to skip analysis on the given document.
 /// </summary>
 /// <param name="sourceCode">
 /// The sourceCode to check.
 /// </param>
 /// <returns>
 /// Returns true to skip analysis on the document.
 /// </returns>
 public virtual bool SkipAnalysisForDocument(SourceCode sourceCode)
 {
     Param.Ignore(sourceCode);
     return false;
 }
Beispiel #31
0
        /// <summary>
        /// Adds the given source code document to the project.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code to add.
        /// </param>
        internal virtual void AddSourceCode(SourceCode sourceCode)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");

            if (string.IsNullOrEmpty(sourceCode.Type))
            {
                throw new ArgumentException(Strings.SourceCodeTypePropertyNotSet);
            }

            this.sourceCodes.Add(sourceCode);
        }
Beispiel #32
0
        /// <summary>
        /// Imports the cached violations under the given node.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code containing the violations.
        /// </param>
        /// <param name="parentNode">
        /// The parent xml node containing the list of violations.
        /// </param>
        /// <returns>
        /// Returns true if all the data was loaded successfully from the file.
        /// </returns>
        internal bool ImportViolations(SourceCode sourceCode, XmlNode parentNode)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(parentNode, "parentNode");

            bool success = true;

            try
            {
                XmlNodeList violations = parentNode.SelectNodes("violation");
                if (violations != null && violations.Count > 0)
                {
                    foreach (XmlNode violationNode in violations)
                    {
                        // Get the violation data from the xml node.
                        XmlNode nameSpace   = violationNode.SelectSingleNode("@namespace");
                        XmlNode ruleName    = violationNode.SelectSingleNode("@rule");
                        XmlNode ruleCheckId = violationNode.SelectSingleNode("@ruleCheckId");
                        XmlNode context     = violationNode.SelectSingleNode("context");
                        XmlNode lineNumber  = violationNode.SelectSingleNode("line");
                        XmlNode warning     = violationNode.SelectSingleNode("warning");

                        XmlNode index       = violationNode.SelectSingleNode("index");
                        XmlNode endIndex    = violationNode.SelectSingleNode("endIndex");
                        XmlNode startLine   = violationNode.SelectSingleNode("startLine");
                        XmlNode startColumn = violationNode.SelectSingleNode("startColumn");
                        XmlNode endLine     = violationNode.SelectSingleNode("endLine");
                        XmlNode endColumn   = violationNode.SelectSingleNode("endColumn");

                        // Create a Rule object representing this data.
                        Rule rule = new Rule(
                            ruleName.InnerText,
                            nameSpace.InnerText,
                            ruleCheckId.InnerText,
                            context.InnerText,
                            Convert.ToBoolean(warning.InnerText, CultureInfo.InvariantCulture));

                        Violation violation;

                        if (startLine != null && startColumn != null && endLine != null && endColumn != null)
                        {
                            CodeLocation location = new CodeLocation(
                                Convert.ToInt32(index.InnerText, null),
                                Convert.ToInt32(endIndex.InnerText, null),
                                Convert.ToInt32(startColumn.InnerText, null),
                                Convert.ToInt32(endColumn.InnerText, null),
                                Convert.ToInt32(startLine.InnerText, null),
                                Convert.ToInt32(endLine.InnerText, null));

                            // Create a Violation object representing this data.
                            violation = new Violation(rule, sourceCode, location, context.InnerText);
                        }
                        else
                        {
                            // Create a Violation object representing this data.
                            violation = new Violation(rule, sourceCode, Convert.ToInt32(lineNumber.InnerText, null), context.InnerText);
                        }

                        this.AddViolation(violation);
                    }
                }
            }
            catch (ArgumentException)
            {
                success = false;
            }
            catch (XmlException)
            {
                success = false;
            }
            catch (FormatException)
            {
                success = false;
            }
            catch (OverflowException)
            {
                success = false;
            }

            return(success);
        }
Beispiel #33
0
 /// <summary>
 /// Indicates whether to skip analysis on the given document.
 /// </summary>
 /// <param name="sourceCode">
 /// The sourceCode to check.
 /// </param>
 /// <returns>
 /// Returns true to skip analysis on the document.
 /// </returns>
 public virtual bool SkipAnalysisForDocument(SourceCode sourceCode)
 {
     Param.Ignore(sourceCode);
     return(false);
 }
Beispiel #34
0
        /// <summary>
        /// Called when a violation is found.
        /// </summary>
        /// <param name="sender">The event sender.</param>
        /// <param name="e">The event arguments.</param>
        private void CoreViolationEncountered(object sender, ViolationEventArgs e)
        {
            Param.Ignore(sender, e);

            lock (this)
            {
                // Create the violation element.
                XmlElement   violation = this.violations.CreateElement("Violation");
                XmlAttribute attrib    = null;

                // Add the element section if it's not empty.
                if (e.Element != null)
                {
                    attrib       = this.violations.CreateAttribute("Section");
                    attrib.Value = CreateSafeSectionName(e.Element.FullyQualifiedName);
                    violation.Attributes.Append(attrib);
                }

                // Add the line number.
                attrib       = this.violations.CreateAttribute("LineNumber");
                attrib.Value = e.LineNumber.ToString(CultureInfo.InvariantCulture);
                violation.Attributes.Append(attrib);

                // Get the source code that this element is in.
                SourceCode sourceCode = e.SourceCode;
                if (sourceCode == null && e.Element != null && e.Element.Document != null)
                {
                    sourceCode = e.Element.Document.SourceCode;
                }

                // Add the source code path.
                if (sourceCode != null)
                {
                    attrib       = this.violations.CreateAttribute("Source");
                    attrib.Value = sourceCode.Path;
                    violation.Attributes.Append(attrib);
                }

                // Add the rule namespace.
                attrib       = this.violations.CreateAttribute("RuleNamespace");
                attrib.Value = e.Violation.Rule.Namespace;
                violation.Attributes.Append(attrib);

                // Add the rule name.
                attrib       = this.violations.CreateAttribute("Rule");
                attrib.Value = e.Violation.Rule.Name;
                violation.Attributes.Append(attrib);

                // Add the rule ID.
                attrib       = this.violations.CreateAttribute("RuleId");
                attrib.Value = e.Violation.Rule.CheckId;
                violation.Attributes.Append(attrib);

                violation.InnerText = e.Message;

                this.violations.DocumentElement.AppendChild(violation);
                this.violationCount++;
            }

            // Forward event
            this.OnViolationEncountered(new ViolationEventArgs(e.Violation));
        }
Beispiel #35
0
        /// <summary>
        /// Parses the given file.
        /// </summary>
        /// <param name="sourceCode">The source code to parse.</param>
        /// <param name="passNumber">The current pass number.</param>
        /// <param name="document">The parsed representation of the file.</param>
        /// <returns>Returns false if no further analysis should be done on this file, or
        /// true if the file should be parsed again during the next pass.</returns>
        public override bool ParseFile(SourceCode sourceCode, int passNumber, ref ICodeDocument document)
        {
            Param.RequireNotNull(sourceCode, "sourceCode");
            Param.RequireGreaterThanOrEqualToZero(passNumber, "passNumber");
            Param.Ignore(document);

            // The document is parsed on the first pass. On any subsequent passes, we do not do anything.
            if (passNumber == 0)
            {
                try
                {
                    using (TextReader reader = sourceCode.Read())
                    {
                        // Create the document.
                        if (reader == null)
                        {
                            this.AddViolation(sourceCode, 1, Rules.FileMustBeReadable);
                        }
                        else
                        {
                            CsLanguageService languageService = new CsLanguageService();
                            
                            document = new CsDocumentWrapper(
                                this, 
                                sourceCode, 
                                languageService.CreateCodeModel(reader, sourceCode.Name, sourceCode.Path));
                        }
                    }
                }
                catch (SyntaxException syntaxex)
                {
                    this.AddViolation(sourceCode, syntaxex.LineNumber, Rules.SyntaxException, syntaxex.Message);
                    document = null;
                }
            }

            return false;
        }
Beispiel #36
0
        public void DoWork(object sender)
        {
            Param.Ignore(sender);
            StyleCopTrace.In(sender);

            // This flag will indicated whether any source code documents need to passed through
            // another round of analysis after this one is completed.
            this.complete = true;

            SourceCode sourceCode = null;

            try
            {
                // Keep looping until all the source code documents have been processed.
                while (!this.data.Core.Cancel)
                {
                    DocumentAnalysisStatus documentStatus;

                    lock (this.data)
                    {
                        // Get the next document to analyze.
                        sourceCode = this.data.GetNextSourceCodeDocument();
                        if (sourceCode == null)
                        {
                            // There are no more documents. Break out of the loop.
                            break;
                        }

                        // Get the status object for this document.
                        documentStatus = this.data.GetDocumentStatus(sourceCode);
                        Debug.Assert(documentStatus != null, "There is no DocumentStatus for the given SourceCode.");
                    }

                    // If this is the first time we have seen this document, prepare it for analysis.
                    if (!documentStatus.Initialized)
                    {
                        // If the document does not exist, or if the document's analysis data can
                        // be loaded from the results cache, mark the document as completed.
                        if (!sourceCode.Exists || this.LoadSourceCodeFromResultsCache(sourceCode))
                        {
                            documentStatus.Complete = true;
                        }

                        // Note that the document status has been initialized now.
                        documentStatus.Initialized = true;
                    }

                    // Check whether this document needs further parsing.
                    if (!documentStatus.Complete)
                    {
                        this.ParseAndAnalyzeDocument(sourceCode, documentStatus);
                    }
                }
            }
            catch (OutOfMemoryException)
            {
                // Do not catch out of memory exceptions.
                throw;
            }
            catch (ThreadAbortException)
            {
                // The thread is being aborted. Stop this thread from doing any additional analysis.
            }
            catch (Exception ex)
            {
                // Catch exceptions from the parser and analyzer modules.
                System.Diagnostics.Trace.WriteLine(string.Format(CultureInfo.CurrentCulture, "Exception occurred: {0}, {1}", ex.GetType(), ex.Message));
                this.data.Core.CoreViolations.AddViolation(sourceCode, 1, Rules.ExceptionOccurred, ex.GetType(), FormatExceptionMessage(ex));

                // Do not re-throw the exception as this can crash Visual Studio or the build system that StyleCop is running under.
            }
            finally
            {
                // Fire the completion event if necessary. When running under Visual Studio using MSBuild, the standard
                // completion event from the BackgroundWorker class does not get fired. The reason is unknown. We fire
                // our own event instead to get around this problem.
                if (this.ThreadCompleted != null)
                {
                    this.ThreadCompleted(this, new EventArgs());
                }
            }

            StyleCopTrace.Out();
        }
Beispiel #37
0
        /// <summary>
        /// Parses and analyzes the given document.
        /// </summary>
        /// <param name="sourceCode">
        /// The document to parse and analyze.
        /// </param>
        /// <param name="documentStatus">
        /// The current status of the documents.
        /// </param>
        private void ParseAndAnalyzeDocument(SourceCode sourceCode, DocumentAnalysisStatus documentStatus)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(documentStatus, "documentStatus");
            StyleCopTrace.In(sourceCode, documentStatus);

            // Signal the output for this document.
            this.data.Core.SignalOutput(
                MessageImportance.Low, string.Format(CultureInfo.CurrentCulture, "Pass {0}:   {1}", this.data.PassNumber + 1, GetSignalOutputGetText(sourceCode)));

            // Extract the document to parse.
            CodeDocument parsedDocument = documentStatus.Document;

            // Get or load the analyzer list.
            IEnumerable <SourceAnalyzer> analyzers = sourceCode.Settings.EnabledAnalyzers;

            // Parse the document.
            bool parsingCompleted;

            try
            {
                parsingCompleted = !sourceCode.Parser.ParseFile(sourceCode, this.data.PassNumber, ref parsedDocument);
            }
            catch (Exception)
            {
                string details = string.Format(
                    CultureInfo.CurrentCulture,
                    "Exception thrown by parser '{0}' while processing '{1}'.",
                    sourceCode.Parser.Name,
                    sourceCode.Path);
                this.data.Core.SignalOutput(MessageImportance.High, details);
                throw;
            }

            if (parsingCompleted)
            {
                if (parsedDocument == null)
                {
                    string format = string.Format(CultureInfo.CurrentCulture, "Skipping: {0} - {1}", sourceCode.Project.Location.SubstringAfterLast('\\'), GetRelativeFileName(sourceCode));
                    this.data.Core.SignalOutput(MessageImportance.Normal, format);

                    documentStatus.Complete = true;
                }
                else if (this.TestAndRunAnalyzers(parsedDocument, sourceCode.Parser, analyzers, this.data.PassNumber))
                {
                    // Analysis of this document is completed.
                    documentStatus.Complete = true;

                    // Save the cache for this document and dispose it.
                    if (this.data.ResultsCache != null && sourceCode.Project.WriteCache)
                    {
                        this.data.ResultsCache.SaveDocumentResults(parsedDocument, sourceCode.Parser, sourceCode.Settings.WriteTime);
                    }

                    parsedDocument.Dispose();
                    parsedDocument = null;
                }
            }

            if (!documentStatus.Complete)
            {
                // Analysis of this document is not complete, so we will need to
                // perform another round of analysis after this one is finished.
                this.complete = false;

                // Cache the document if there is one.
                if (parsedDocument != null)
                {
                    documentStatus.Document = parsedDocument;
                }
            }

            StyleCopTrace.Out();
        }
Beispiel #38
0
 public abstract bool ParseFile(SourceCode sourceCode, int passNumber, ref ICodeDocument document);
        /// <summary>
        /// Initializes a new instance of the Violation class.
        /// </summary>
        /// <param name="rule">
        /// The rule that triggered the violation.
        /// </param>
        /// <param name="element">
        /// The element that this violation appears in.
        /// </param>
        /// <param name="line">
        /// The line in the source code where the violation occurs.
        /// </param>
        /// <param name="message">
        /// The context message for the violation.
        /// </param>
        internal Violation(Rule rule, ICodeElement element, int line, string message)
        {
            Param.AssertNotNull(rule, "rule");
            Param.Ignore(element);
            Param.AssertGreaterThanOrEqualToZero(line, "line");
            Param.AssertNotNull(message, "message");

            this.rule = rule;
            this.element = element;
            this.line = line;

            // As the line only is passed in we ensure the location is null.
            // A null location indicates we only know the line it was on.
            this.location = null;
            this.message = message;

            if (this.element != null && this.element.Document != null)
            {
                this.sourceCode = this.element.Document.SourceCode;
            }

            this.UpdateKey();
        }
Beispiel #40
0
 /// <summary>
 /// Parses a source code document.
 /// </summary>
 /// <param name="sourceCode">
 /// The source code to parse.
 /// </param>
 /// <param name="passNumber">
 /// The current pass number.
 /// </param>
 /// <param name="document">
 /// The parsed representation of the file.
 /// </param>
 /// <returns>
 /// Returns false if no further parsing should be done on this file.
 /// </returns>
 public override bool ParseFile(SourceCode sourceCode, int passNumber, ref CodeDocument document)
 {
     Param.Ignore(sourceCode, passNumber, document);
     throw new NotImplementedException();
 }
        /// <summary>
        /// Disposes the contents of the class.
        /// </summary>
        /// <param name="disposing">
        /// Indicates whether to dispose unmanaged resources.
        /// </param>
        protected virtual void Dispose(bool disposing)
        {
            Param.Ignore(disposing);

            if (disposing)
            {
                this.sourceCode = null;
                this.analyzerData = null;
            }
        }
Beispiel #42
0
 /// <summary>
 /// Parses a source code document.
 /// </summary>
 /// <param name="sourceCode">The source code to parse.</param>
 /// <param name="passNumber">The current pass number.</param>
 /// <param name="document">The parsed representation of the file.</param>
 /// <returns>Returns false if no further analyzation should be done on this file.</returns>
 public override bool ParseFile(SourceCode sourceCode, int passNumber, ref ICodeDocument document)
 {
     Param.Ignore(sourceCode, passNumber, document);
     throw new NotImplementedException();
 }
        /// <summary>
        /// Initializes a new instance of the Violation class.
        /// </summary>
        /// <param name="rule">
        /// The rule that triggered the violation.
        /// </param>
        /// <param name="element">
        /// The element that this violation appears in.
        /// </param>
        /// <param name="location">
        /// The location in the source code where the violation occurs.
        /// </param>
        /// <param name="message">
        /// The context message for the violation.
        /// </param>
        internal Violation(Rule rule, ICodeElement element, CodeLocation location, string message)
        {
            Param.AssertNotNull(rule, "rule");
            Param.Ignore(element);
            Param.AssertNotNull(location, "location");
            Param.AssertNotNull(message, "message");

            this.rule = rule;
            this.element = element;

            // The CodeLocation passed in is zero based everywhere in StyleCop for the column. The line number is already 1 based.
            // We convert is to 1 based here so that are xml reports etc and VisualStudio UI friendly.
            this.location = new CodeLocation(
                location.StartPoint.Index, 
                location.EndPoint.Index, 
                location.StartPoint.IndexOnLine + 1, 
                location.EndPoint.IndexOnLine + 1, 
                location.StartPoint.LineNumber, 
                location.EndPoint.LineNumber);

            // If the location has been passed in we set the linenumber.
            this.line = location.LineNumber;
            this.message = message;

            if (this.element != null && this.element.Document != null)
            {
                this.sourceCode = this.element.Document.SourceCode;
            }

            this.UpdateKey();
        }
Beispiel #44
0
        /// <summary>
        /// Parses and analyzes the given document.
        /// </summary>
        /// <param name="sourceCode">The document to parse and analyze.</param>
        /// <param name="documentStatus">The current status of the documents.</param>
        private void ParseAndAnalyzeDocument(SourceCode sourceCode, DocumentAnalysisStatus documentStatus)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(documentStatus, "documentStatus");

            // Signal the output for this document.
            this.data.Core.SignalOutput(
                MessageImportance.Low,
                string.Format(CultureInfo.CurrentCulture, "Pass {0}: {1}...\n", this.data.PassNumber + 1, sourceCode.Name));

            // Extract the document to parse.
            ICodeDocument parsedDocument = documentStatus.Document;

            // Get or load the analyzer list.
            IEnumerable <SourceAnalyzer> analyzers = sourceCode.Settings.EnabledAnalyzers;

            // Parse the document.
            bool parsingCompleted;

            try
            {
                parsingCompleted = !sourceCode.Parser.ParseFile(sourceCode, this.data.PassNumber, ref parsedDocument);
            }
            catch (System.Exception)
            {
                string details = string.Format(
                    CultureInfo.CurrentCulture,
                    "Exception thrown by parser '{0}' while processing '{1}'.",
                    sourceCode.Parser.Name,
                    sourceCode.Path);

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

            if (parsingCompleted)
            {
                if (parsedDocument == null)
                {
                    documentStatus.Complete = true;
                }
                else
                {
                    if (this.data.RunContext.AutoFix)
                    {
                        parsedDocument.ReadOnly = false;
                    }

                    if (this.TestAndRunAnalyzers(parsedDocument, sourceCode.Parser, analyzers, this.data.PassNumber))
                    {
                        // Analysis of this document is completed.
                        documentStatus.Complete = true;

                        // Save the cache for this document and dispose it.
                        if (parsedDocument != null)
                        {
                            if (this.data.ResultsCache != null && sourceCode.Project.WriteCache)
                            {
                                this.data.ResultsCache.SaveDocumentResults(parsedDocument, sourceCode.Parser, sourceCode.Settings.WriteTime);
                            }

                            // If auto-save is true, then save the doc.
                            if (this.data.RunContext.AutoFix && this.data.AutoSaveMode && parsedDocument.Dirty)
                            {
                                this.SaveDocumentToSource(sourceCode, parsedDocument);
                            }

                            parsedDocument.Dispose();
                            parsedDocument = null;
                        }
                    }
                }
            }

            if (!documentStatus.Complete)
            {
                // Analysis of this document is not complete, so we will need to
                // perform another round of analysis after this one is finished.
                this.complete = false;

                // Cache the document if there is one.
                if (parsedDocument != null)
                {
                    documentStatus.Document = parsedDocument;
                }
            }
        }
        private bool RegionEndCheckIfBlankOrCurly(SourceCode codeFile, int linenumber, bool allowCurly = true)
        {
            var myReader = codeFile.Read();
            for (var i = 1; i <= linenumber; i++)
            {
                var data = myReader.ReadLine();
                if (i == linenumber)
                {
                    if (data.Trim() == string.Empty || (data.Trim().Contains("}") && allowCurly))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        private bool RegionStartCheckIfBlankOrCurly(SourceCode codeFile, int linenumber, bool allowCurly = true)
        {
            var myReader = codeFile.Read();
            for (var i = 1; i <= linenumber; i++)
            {
                var data = myReader.ReadLine();
                if (i == linenumber)
                {
                    //_logFile.WriteLine("LineNumber: {0} -- Text: {1}", linenumber, data);

                    if (data.Trim() == string.Empty || (data.Trim().Contains("{") && allowCurly))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
        /// <summary>
        /// Returns the leafname of the source code path.
        /// </summary>
        /// <param name="sourceCode">
        /// The SourceCode object to use.
        /// </param>
        /// <returns>
        /// The leafname.
        /// </returns>
        private static string GetRelativeFileName(SourceCode sourceCode)
        {
            string sourceCodePath = sourceCode.Path;
            string sourceCodeProjectLocation = sourceCode.Project.Location;
            string outputText = sourceCode.Name;

            if (sourceCodePath != null && sourceCodeProjectLocation != null && sourceCodePath.StartsWith(sourceCodeProjectLocation, true, CultureInfo.InvariantCulture))
            {
                outputText = sourceCodePath.SubstringAfter(sourceCodeProjectLocation, StringComparison.InvariantCultureIgnoreCase);
            }

            return outputText;
        }
 /// <summary>
 /// Initializes a new instance of the CodeDocument class.
 /// </summary>
 /// <param name="sourceCode">
 /// The source code document this instance represents.
 /// </param>
 protected CodeDocument(SourceCode sourceCode)
 {
     Param.RequireNotNull(sourceCode, "sourceCode");
     this.sourceCode = sourceCode;
 }
 /// <summary>
 /// Returns the text to use in the signalled output.
 /// </summary>
 /// <param name="sourceCode">
 /// The SourceCode object to use.
 /// </param>
 /// <returns>
 /// The text to signal.
 /// </returns>
 private static string GetSignalOutputGetText(SourceCode sourceCode)
 {
     string relativeFileName = GetRelativeFileName(sourceCode);
     return sourceCode.Project.Location == null
                ? relativeFileName
                : string.Format(CultureInfo.CurrentCulture, "{0} - {1}", sourceCode.Project.Location.SubstringAfterLast('\\'), relativeFileName);
 }
Beispiel #50
0
        /// <summary>
        /// Adds a generic violation.
        /// </summary>
        /// <param name="sourceCode">The source code document to add the violation to.</param>
        /// <param name="type">The type of violation to add.</param>
        /// <param name="line">Line the violation appears on.</param>
        /// <param name="values">The string values to add to the context string.</param>
        internal void AddViolation(SourceCode sourceCode, Rule type, int line, params object[] values)
        {
            Param.Ignore(sourceCode);
            Param.AssertNotNull(type, "type");
            Param.AssertGreaterThanZero(line, "line");
            Param.Ignore(values);

            // Build up the context string.
            StringBuilder message = new StringBuilder();
            message.AppendFormat(CultureInfo.CurrentCulture, type.Context, values);

            // Create the violation object and add it to the list.
            Violation violation = new Violation(type, sourceCode, line, message.ToString());

            // Finally, add the violation.
            this.AddViolation(sourceCode, violation);
        }
        /// <summary>
        /// Attempts to load results for the given document from the cache.
        /// </summary>
        /// <param name="sourceCode">
        /// The source code document to load.
        /// </param>
        /// <returns>
        /// Returns true if the results were loaded from the cache.
        /// </returns>
        private bool LoadSourceCodeFromResultsCache(SourceCode sourceCode)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");

            if (!this.data.IgnoreResultsCache && this.data.Core.Environment.SupportsResultsCache && this.data.ResultsCache != null)
            {
                // Check the project to see if the cache should be ignored.
                ProjectStatus projectStatus = this.data.GetProjectStatus(sourceCode.Project);
                Debug.Assert(projectStatus != null, "There is no status for the given project.");

                if (!projectStatus.IgnoreResultsCache)
                {
                    // Get the last write time for this file.
                    DateTime lastWriteTime = sourceCode.TimeStamp;

                    // Attempt to load the file from the cache.
                    if (this.data.ResultsCache.LoadResults(sourceCode, sourceCode.Parser, lastWriteTime, sourceCode.Project.Settings.WriteTime))
                    {
                        return true;
                    }
                }
            }

            return false;
        }
Beispiel #52
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;
        }
        /// <summary>
        /// Parses and analyzes the given document.
        /// </summary>
        /// <param name="sourceCode">
        /// The document to parse and analyze.
        /// </param>
        /// <param name="documentStatus">
        /// The current status of the documents.
        /// </param>
        private void ParseAndAnalyzeDocument(SourceCode sourceCode, DocumentAnalysisStatus documentStatus)
        {
            Param.AssertNotNull(sourceCode, "sourceCode");
            Param.AssertNotNull(documentStatus, "documentStatus");
            StyleCopTrace.In(sourceCode, documentStatus);

            // Signal the output for this document.
            this.data.Core.SignalOutput(
                MessageImportance.Low, string.Format(CultureInfo.CurrentCulture, "Pass {0}:   {1}", this.data.PassNumber + 1, GetSignalOutputGetText(sourceCode)));

            // Extract the document to parse.
            CodeDocument parsedDocument = documentStatus.Document;

            // Get or load the analyzer list.
            IEnumerable<SourceAnalyzer> analyzers = sourceCode.Settings.EnabledAnalyzers;

            // Parse the document.
            bool parsingCompleted;
            try
            {
                parsingCompleted = !sourceCode.Parser.ParseFile(sourceCode, this.data.PassNumber, ref parsedDocument);
            }
            catch (Exception)
            {
                string details = string.Format(
                    CultureInfo.CurrentCulture,
                    "Exception thrown by parser '{0}' while processing '{1}'.",
                    sourceCode.Parser.Name,
                    sourceCode.Path);
                this.data.Core.SignalOutput(MessageImportance.High, details);
                throw;
            }

            if (parsingCompleted)
            {
                if (parsedDocument == null)
                {
                    string format = string.Format(CultureInfo.CurrentCulture, "Skipping: {0} - {1}", sourceCode.Project.Location.SubstringAfterLast('\\'), GetRelativeFileName(sourceCode));
                    this.data.Core.SignalOutput(MessageImportance.Normal, format);

                    documentStatus.Complete = true;
                }
                else if (this.TestAndRunAnalyzers(parsedDocument, sourceCode.Parser, analyzers, this.data.PassNumber))
                {
                    // Analysis of this document is completed.
                    documentStatus.Complete = true;

                    // Save the cache for this document and dispose it.
                    if (this.data.ResultsCache != null && sourceCode.Project.WriteCache)
                    {
                        this.data.ResultsCache.SaveDocumentResults(parsedDocument, sourceCode.Parser, sourceCode.Settings.WriteTime);
                    }

                    parsedDocument.Dispose();
                    parsedDocument = null;
                }
            }

            if (!documentStatus.Complete)
            {
                // Analysis of this document is not complete, so we will need to 
                // perform another round of analysis after this one is finished.
                this.complete = false;

                // Cache the document if there is one.
                if (parsedDocument != null)
                {
                    documentStatus.Document = parsedDocument;
                }
            }

            StyleCopTrace.Out();
        }
        private static CsDocument Parse(SourceCode code, CodeProject project)
        {
            CodeDocument codeDocument = null;

            code.Parser.PreParse();
            try
            {
                var requiredNextPass = code.Parser.ParseFile(code, 0, ref codeDocument);
            }
            catch (ArgumentException)
            {
                if (DoNotSuppressExceptions)
                {
                    throw;
                }
            }
            finally
            {
                code.Parser.PostParse();
            }

            return (CsDocument)codeDocument;
        }
Beispiel #55
0
 public abstract bool ParseFile(SourceCode sourceCode, int passNumber, ref ICodeDocument document);