public static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopSettings settings)
            {
                var syntaxRoot = context.Tree.GetRoot(context.CancellationToken);

                var firstTypeDeclaration = GetFirstTypeDeclaration(syntaxRoot);
                if (firstTypeDeclaration == null)
                {
                    return;
                }

                if (firstTypeDeclaration.Modifiers.Any(SyntaxKind.PartialKeyword))
                {
                    return;
                }

                string suffix;
                var fileName = FileNameHelpers.GetFileNameAndSuffix(context.Tree.FilePath, out suffix);
                var expectedFileName = FileNameHelpers.GetConventionalFileName(firstTypeDeclaration, settings.DocumentationRules.FileNamingConvention);

                if (string.Compare(fileName, expectedFileName, StringComparison.OrdinalIgnoreCase) != 0)
                {
                    if (settings.DocumentationRules.FileNamingConvention == FileNamingConvention.StyleCop
                        && string.Compare(fileName, FileNameHelpers.GetSimpleFileName(firstTypeDeclaration), StringComparison.OrdinalIgnoreCase) == 0)
                    {
                        return;
                    }

                    var properties = ImmutableDictionary.Create<string, string>()
                        .Add(ExpectedFileNameKey, expectedFileName + suffix);

                    context.ReportDiagnostic(Diagnostic.Create(Descriptor, firstTypeDeclaration.Identifier.GetLocation(), properties));
                }
            }
        private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopSettings settings)
        {
            SyntaxNode root = context.Tree.GetCompilationUnitRoot(context.CancellationToken);
            ImmutableArray<TextSpan> excludedSpans;
            if (!LocateExcludedSpans(root, out excludedSpans))
            {
                return;
            }

            ReportIncorrectTabUsage(context, settings.Indentation, excludedSpans);
        }
        private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder = settings.OrderingRules.ElementOrder;
            int staticIndex = elementOrder.IndexOf(OrderingTrait.Static);
            if (staticIndex < 0)
            {
                return;
            }

            var compilationUnit = (NamespaceDeclarationSyntax)context.Node;

            HandleMemberList(context, elementOrder, staticIndex, compilationUnit.Members);
        }
        private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            if (!settings.OrderingRules.SystemUsingDirectivesFirst)
            {
                return;
            }

            var compilationUnit = context.Node as CompilationUnitSyntax;

            var usings = compilationUnit.Usings;

            ProcessUsingsAndReportDiagnostic(usings, context);
        }
        private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            if (!settings.OrderingRules.SystemUsingDirectivesFirst)
            {
                return;
            }

            var namespaceDeclaration = context.Node as NamespaceDeclarationSyntax;

            var usings = namespaceDeclaration.Usings;

            ProcessUsingsAndReportDiagnostic(usings, context);
        }
        private static SyntaxNode ReplaceHeader(Document document, SyntaxNode root, StyleCopSettings settings)
        {
            // Skip single line comments, whitespace, and end of line trivia until a blank line is encountered.
            SyntaxTriviaList trivia = root.GetLeadingTrivia();

            bool onBlankLine = false;
            while (trivia.Any())
            {
                bool done = false;
                switch (trivia[0].Kind())
                {
                case SyntaxKind.SingleLineCommentTrivia:
                    trivia = trivia.RemoveAt(0);
                    onBlankLine = false;
                    break;

                case SyntaxKind.WhitespaceTrivia:
                    trivia = trivia.RemoveAt(0);
                    break;

                case SyntaxKind.EndOfLineTrivia:
                    trivia = trivia.RemoveAt(0);

                    if (onBlankLine)
                    {
                        done = true;
                    }
                    else
                    {
                        onBlankLine = true;
                    }

                    break;

                default:
                    done = true;
                    break;
                }

                if (done)
                {
                    break;
                }
            }

            string newLineText = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
            return root.WithLeadingTrivia(CreateNewHeader(document.Name, settings, newLineText).Add(SyntaxFactory.CarriageReturnLineFeed).Add(SyntaxFactory.CarriageReturnLineFeed).AddRange(trivia));
        }
            public static void HandleEnumMemberDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
            {
                if (context.GetDocumentationMode() != DocumentationMode.Diagnose)
                {
                    return;
                }

                EnumMemberDeclarationSyntax declaration = (EnumMemberDeclarationSyntax)context.Node;
                Accessibility declaredAccessibility = declaration.GetDeclaredAccessibility();
                Accessibility effectiveAccessibility = declaration.GetEffectiveAccessibility(context.SemanticModel, context.CancellationToken);
                if (NeedsComment(settings.DocumentationRules, declaration.Kind(), declaration.Parent.Kind(), declaredAccessibility, effectiveAccessibility))
                {
                    if (!XmlCommentHelper.HasDocumentation(declaration))
                    {
                        context.ReportDiagnostic(Diagnostic.Create(Descriptor, declaration.Identifier.GetLocation()));
                    }
                }
            }
        private static void CheckCopyrightHeader(SyntaxTreeAnalysisContext context, Compilation compilation, StyleCopSettings settings, XmlFileHeader fileHeader)
        {
            var copyrightElement = fileHeader.GetElement("copyright");
            if (copyrightElement == null)
            {
                context.ReportDiagnostic(Diagnostic.Create(SA1634Descriptor, fileHeader.GetLocation(context.Tree)));
                return;
            }

            if (!compilation.IsAnalyzerSuppressed(SA1637Identifier))
            {
                CheckFile(context, compilation, fileHeader, copyrightElement, settings);
            }

            if (!compilation.IsAnalyzerSuppressed(SA1640Identifier))
            {
                CheckCompanyName(context, compilation, fileHeader, copyrightElement, settings);
            }

            if (!compilation.IsAnalyzerSuppressed(SA1635Identifier))
            {
                CheckCopyrightText(context, compilation, fileHeader, copyrightElement, settings);
            }
        }
        private static void CheckFile(SyntaxTreeAnalysisContext context, Compilation compilation, XmlFileHeader fileHeader, XElement copyrightElement, StyleCopSettings settings)
        {
            var fileAttribute = copyrightElement.Attribute("file");
            if (fileAttribute == null)
            {
                var location = fileHeader.GetElementLocation(context.Tree, copyrightElement);
                context.ReportDiagnostic(Diagnostic.Create(SA1637Descriptor, location));
                return;
            }

            if (compilation.IsAnalyzerSuppressed(SA1638Identifier))
            {
                return;
            }

            var fileName = Path.GetFileName(context.Tree.FilePath);
            if (string.CompareOrdinal(fileAttribute.Value, fileName) != 0)
            {
                var location = fileHeader.GetElementLocation(context.Tree, copyrightElement);
                context.ReportDiagnostic(Diagnostic.Create(SA1638Descriptor, location));
            }
        }
        private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopSettings settings)
        {
            var endOfFileToken = context.Tree.GetRoot().GetLastToken(includeZeroWidth: true);
            TextSpan reportedSpan = new TextSpan(endOfFileToken.SpanStart, 0);

            SyntaxTrivia precedingTrivia = default(SyntaxTrivia);
            bool checkPrecedingToken;
            if (endOfFileToken.HasLeadingTrivia)
            {
                var leadingTrivia = endOfFileToken.LeadingTrivia;
                var trailingWhitespaceIndex = TriviaHelper.IndexOfTrailingWhitespace(leadingTrivia);
                if (trailingWhitespaceIndex > 0)
                {
                    checkPrecedingToken = false;
                    reportedSpan = TextSpan.FromBounds(leadingTrivia[trailingWhitespaceIndex].SpanStart, reportedSpan.End);
                    precedingTrivia = leadingTrivia[trailingWhitespaceIndex - 1];
                }
                else if (trailingWhitespaceIndex == 0)
                {
                    checkPrecedingToken = true;
                    reportedSpan = TextSpan.FromBounds(leadingTrivia[trailingWhitespaceIndex].SpanStart, reportedSpan.End);
                }
                else
                {
                    checkPrecedingToken = false;
                    precedingTrivia = leadingTrivia.Last();
                }
            }
            else
            {
                checkPrecedingToken = true;
            }

            if (checkPrecedingToken)
            {
                var previousToken = endOfFileToken.GetPreviousToken(includeZeroWidth: true, includeSkipped: true, includeDirectives: true, includeDocumentationComments: true);
                var trailingWhitespaceIndex = TriviaHelper.IndexOfTrailingWhitespace(previousToken.TrailingTrivia);
                if (trailingWhitespaceIndex > 0)
                {
                    reportedSpan = TextSpan.FromBounds(previousToken.TrailingTrivia[trailingWhitespaceIndex].SpanStart, reportedSpan.End);
                    precedingTrivia = previousToken.TrailingTrivia[trailingWhitespaceIndex - 1];
                }
                else if (trailingWhitespaceIndex == 0)
                {
                    reportedSpan = TextSpan.FromBounds(previousToken.TrailingTrivia[trailingWhitespaceIndex].SpanStart, reportedSpan.End);
                    precedingTrivia = default(SyntaxTrivia);
                }
                else
                {
                    if (previousToken.TrailingTrivia.Count > 0)
                    {
                        precedingTrivia = previousToken.TrailingTrivia.Last();
                    }
                }
            }

            if (precedingTrivia.IsDirective)
            {
                DirectiveTriviaSyntax directiveTriviaSyntax = precedingTrivia.GetStructure() as DirectiveTriviaSyntax;
                if (directiveTriviaSyntax != null && directiveTriviaSyntax.EndOfDirectiveToken.HasTrailingTrivia)
                {
                    var trailingWhitespaceIndex = TriviaHelper.IndexOfTrailingWhitespace(directiveTriviaSyntax.EndOfDirectiveToken.TrailingTrivia);
                    if (trailingWhitespaceIndex >= 0)
                    {
                        reportedSpan = TextSpan.FromBounds(directiveTriviaSyntax.EndOfDirectiveToken.TrailingTrivia[trailingWhitespaceIndex].SpanStart, reportedSpan.End);
                    }
                }
            }
            else if (precedingTrivia.IsKind(SyntaxKind.EndOfLineTrivia))
            {
                reportedSpan = TextSpan.FromBounds(precedingTrivia.SpanStart, reportedSpan.End);
            }

            SourceText sourceText = context.Tree.GetText(context.CancellationToken);
            string trailingWhitespaceText = sourceText.ToString(reportedSpan);
            int firstNewline = trailingWhitespaceText.IndexOf('\n');
            int secondNewline = firstNewline >= 0 ? trailingWhitespaceText.IndexOf('\n', firstNewline + 1) : -1;

            DiagnosticDescriptor descriptorToReport;
            switch (settings.LayoutRules.NewlineAtEndOfFile)
            {
            case EndOfFileHandling.Omit:
                if (firstNewline < 0)
                {
                    return;
                }

                descriptorToReport = DescriptorOmit;
                break;

            case EndOfFileHandling.Require:
                if (firstNewline >= 0 && firstNewline == trailingWhitespaceText.Length - 1)
                {
                    return;
                }

                descriptorToReport = DescriptorRequire;
                break;

            case EndOfFileHandling.Allow:
            default:
                if (secondNewline < 0)
                {
                    // 1. A newline is allowed but not required
                    // 2. If a newline is included, it cannot be followed by whitespace
                    if (firstNewline < 0 || firstNewline == trailingWhitespaceText.Length - 1)
                    {
                        return;
                    }
                }

                descriptorToReport = DescriptorAllow;
                break;
            }

            context.ReportDiagnostic(Diagnostic.Create(descriptorToReport, Location.Create(context.Tree, reportedSpan)));
        }
Exemplo n.º 11
0
        private static void CheckCopyrightText(SyntaxTreeAnalysisContext context, Compilation compilation, XmlFileHeader fileHeader, XElement copyrightElement, StyleCopSettings settings)
        {
            var copyrightText = copyrightElement.Value;
            if (string.IsNullOrWhiteSpace(copyrightText))
            {
                var location = fileHeader.GetElementLocation(context.Tree, copyrightElement);
                context.ReportDiagnostic(Diagnostic.Create(SA1635Descriptor, location));
                return;
            }

            if (compilation.IsAnalyzerSuppressed(SA1636Identifier))
            {
                return;
            }

            if (string.Equals(settings.DocumentationRules.CopyrightText, DocumentationSettings.DefaultCopyrightText, StringComparison.OrdinalIgnoreCase))
            {
                // The copyright text is meaningless until the company name is configured by the user.
                return;
            }

            if (string.CompareOrdinal(copyrightText.Trim(' ', '\r', '\n'), settings.DocumentationRules.CopyrightText) != 0)
            {
                var location = fileHeader.GetElementLocation(context.Tree, copyrightElement);
                context.ReportDiagnostic(Diagnostic.Create(SA1636Descriptor, location));
            }
        }
        private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var compilationUnit = (CompilationUnitSyntax)context.Node;

            ProcessUsings(context, settings.OrderingRules, compilationUnit.Usings);
        }
        private static void HandleNamespaceDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var namespaceDeclaration = (NamespaceDeclarationSyntax)context.Node;

            ProcessUsings(context, settings.OrderingRules, namespaceDeclaration.Usings);
        }
        private static string WrapInXmlComment(string prefixWithLeadingSpaces, string copyrightText, string filename, StyleCopSettings settings, string newLineText)
        {
            string encodedFilename = new XAttribute("t", filename).ToString().Substring(2).Trim('"');
            string encodedCompanyName = new XAttribute("t", settings.DocumentationRules.CompanyName).ToString().Substring(2).Trim('"');
            string encodedCopyrightText = new XText(copyrightText).ToString();

            return
                $"{prefixWithLeadingSpaces} <copyright file=\"{encodedFilename}\" company=\"{encodedCompanyName}\">" + newLineText
                + encodedCopyrightText + newLineText
                + prefixWithLeadingSpaces + " </copyright>";
        }
        private static string WrapInXmlComment(string copyrightText, string filename, StyleCopSettings settings)
        {
            return $@"// <copyright file=""{filename}"" company=""{settings.DocumentationRules.CompanyName}"">
{copyrightText}
// </copyright>";
        }
Exemplo n.º 16
0
 protected SettingsFile()
 {
     this.settings = new StyleCopSettings();
 }
        private static SyntaxNode AddHeader(Document document, SyntaxNode root, string name, StyleCopSettings settings)
        {
            string newLineText = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
            var newLineTrivia = SyntaxFactory.EndOfLine(newLineText);
            var newTrivia = CreateNewHeader("//", name, settings, newLineText).Add(newLineTrivia).Add(newLineTrivia);
            newTrivia = newTrivia.AddRange(root.GetLeadingTrivia());

            return root.WithLeadingTrivia(newTrivia);
        }
        private static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopSettings settings)
        {
            if (settings.Indentation.UseTabs)
            {
                return;
            }

            SyntaxNode root = context.Tree.GetCompilationUnitRoot(context.CancellationToken);
            foreach (var trivia in root.DescendantTrivia(descendIntoTrivia: true))
            {
                switch (trivia.Kind())
                {
                case SyntaxKind.WhitespaceTrivia:
                case SyntaxKind.DocumentationCommentExteriorTrivia:
                case SyntaxKind.SingleLineCommentTrivia:
                case SyntaxKind.MultiLineCommentTrivia:
                    HandleWhitespaceTrivia(context, trivia);
                    break;

                case SyntaxKind.SingleLineDocumentationCommentTrivia:
                case SyntaxKind.MultiLineDocumentationCommentTrivia:
                    HandleDocumentationCommentTrivia(context, trivia);
                    break;

                default:
                    break;
                }
            }
        }
        /// <summary>
        /// Creates a solution that will be used as parent for the sources that need to be checked.
        /// </summary>
        /// <param name="projectId">The project identifier to use.</param>
        /// <param name="language">The language for which the solution is being created.</param>
        /// <returns>The created solution.</returns>
        protected virtual Solution CreateSolution(ProjectId projectId, string language)
        {
            var compilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary, allowUnsafe: true);

            Solution solution = new AdhocWorkspace()
                .CurrentSolution
                .AddProject(projectId, TestProjectName, TestProjectName, language)
                .WithProjectCompilationOptions(projectId, compilationOptions)
                .AddMetadataReference(projectId, MetadataReferences.CorlibReference)
                .AddMetadataReference(projectId, MetadataReferences.SystemReference)
                .AddMetadataReference(projectId, MetadataReferences.SystemCoreReference)
                .AddMetadataReference(projectId, MetadataReferences.CSharpSymbolsReference)
                .AddMetadataReference(projectId, MetadataReferences.CodeAnalysisReference);

            solution.Workspace.Options =
                solution.Workspace.Options
                .WithChangedOption(FormattingOptions.IndentationSize, language, this.IndentationSize)
                .WithChangedOption(FormattingOptions.TabSize, language, this.TabSize)
                .WithChangedOption(FormattingOptions.UseTabs, language, this.UseTabs);

            var settings = this.GetSettings();

            StyleCopSettings defaultSettings = new StyleCopSettings();
            if (this.IndentationSize != defaultSettings.Indentation.IndentationSize
                || this.UseTabs != defaultSettings.Indentation.UseTabs
                || this.TabSize != defaultSettings.Indentation.TabSize)
            {
                var indentationSettings = $@"
{{
  ""settings"": {{
    ""indentation"": {{
      ""indentationSize"": {this.IndentationSize},
      ""useTabs"": {this.UseTabs.ToString().ToLowerInvariant()},
      ""tabSize"": {this.TabSize}
    }}
  }}
}}
";

                if (string.IsNullOrEmpty(settings))
                {
                    settings = indentationSettings;
                }
                else
                {
                    JObject mergedSettings = JsonConvert.DeserializeObject<JObject>(settings);
                    mergedSettings.Merge(JsonConvert.DeserializeObject<JObject>(indentationSettings));
                    settings = JsonConvert.SerializeObject(mergedSettings);
                }
            }

            if (!string.IsNullOrEmpty(settings))
            {
                var documentId = DocumentId.CreateNewId(projectId);
                solution = solution.AddAdditionalDocument(documentId, SettingsHelper.SettingsFileName, settings);
            }

            ParseOptions parseOptions = solution.GetProject(projectId).ParseOptions;
            return solution.WithProjectParseOptions(projectId, parseOptions.WithDocumentationMode(DocumentationMode.Diagnose));
        }
 private static SyntaxTriviaList CreateNewHeader(string filename, StyleCopSettings settings)
 {
     var copyrightText = "// " + GetCopyrightText(settings.DocumentationRules.CopyrightText);
     var newHeader = settings.DocumentationRules.XmlHeader
         ? WrapInXmlComment(copyrightText, filename, settings)
         : copyrightText;
     return SyntaxFactory.ParseLeadingTrivia(newHeader);
 }
        private static void CheckCompanyName(SyntaxTreeAnalysisContext context, Compilation compilation, XmlFileHeader fileHeader, XElement copyrightElement, StyleCopSettings settings)
        {
            var companyName = copyrightElement.Attribute("company")?.Value;
            if (string.IsNullOrWhiteSpace(companyName))
            {
                var location = fileHeader.GetElementLocation(context.Tree, copyrightElement);
                context.ReportDiagnostic(Diagnostic.Create(SA1640Descriptor, location));
                return;
            }

            if (compilation.IsAnalyzerSuppressed(SA1641Identifier))
            {
                return;
            }

            if (string.CompareOrdinal(companyName, settings.DocumentationRules.CompanyName) != 0)
            {
                var location = fileHeader.GetElementLocation(context.Tree, copyrightElement);
                context.ReportDiagnostic(Diagnostic.Create(SA1641Descriptor, location));
            }
        }
        private static SyntaxNode AddHeader(SyntaxNode root, string name, StyleCopSettings settings)
        {
            var newTrivia = CreateNewHeader(name, settings).Add(SyntaxFactory.CarriageReturnLineFeed).Add(SyntaxFactory.CarriageReturnLineFeed);
            newTrivia = newTrivia.AddRange(root.GetLeadingTrivia());

            return root.WithLeadingTrivia(newTrivia);
        }
        private static void HandleTypeDeclaration(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder = settings.OrderingRules.ElementOrder;
            int accessibilityIndex = elementOrder.IndexOf(OrderingTrait.Accessibility);
            if (accessibilityIndex < 0)
            {
                return;
            }

            var typeDeclaration = (TypeDeclarationSyntax)context.Node;

            HandleMemberList(context, elementOrder, accessibilityIndex, typeDeclaration.Members, AccessLevel.Private);
        }
 private static string WrapInXmlComment(string copyrightText, string filename, StyleCopSettings settings, string newLineText)
 {
     return
         $"// <copyright file=\"{filename}\" company=\"{settings.DocumentationRules.CompanyName}\">" + newLineText
         + copyrightText + newLineText
         + "// </copyright>";
 }
        private static SyntaxNode ReplaceHeader(Document document, SyntaxNode root, StyleCopSettings settings, bool isMalformedHeader)
        {
            // If the header is well formed Xml then we parse out the copyright otherwise
            // Skip single line comments, whitespace, and end of line trivia until a blank line is encountered.
            SyntaxTriviaList trivia = root.GetLeadingTrivia();
            bool onBlankLine = false;
            bool inCopyright = isMalformedHeader;
            int? copyrightTriviaIndex = null;
            var removalList = new System.Collections.Generic.List<int>();
            var leadingSpaces = string.Empty;
            string possibleLeadingSpaces = string.Empty;

            // Need to do this with index so we get the line endings correct.
            for (int i = 0; i < trivia.Count; i++)
            {
                var triviaLine = trivia[i];
                bool done = false;
                switch (triviaLine.Kind())
                {
                case SyntaxKind.SingleLineCommentTrivia:
                    if (possibleLeadingSpaces != string.Empty)
                    {
                        leadingSpaces = possibleLeadingSpaces;
                    }

                    if (!isMalformedHeader)
                    {
                        var openingTag = triviaLine.ToFullString().Contains("<copyright ");
                        var closingTag = triviaLine.ToFullString().Contains("</copyright>") ||
                            (openingTag && triviaLine.ToFullString().Trim().EndsWith("/>"));
                        if (openingTag)
                        {
                            inCopyright = !closingTag;
                            copyrightTriviaIndex = i;
                        }
                        else if (inCopyright)
                        {
                            removalList.Add(i);
                            inCopyright = !closingTag;
                        }
                    }
                    else
                    {
                        removalList.Add(i);
                    }

                    onBlankLine = false;
                    break;

                case SyntaxKind.WhitespaceTrivia:
                    if (leadingSpaces == string.Empty)
                    {
                        possibleLeadingSpaces = triviaLine.ToFullString();
                    }

                    if (inCopyright)
                    {
                        removalList.Add(i);
                    }

                    break;

                case SyntaxKind.EndOfLineTrivia:
                    if (inCopyright)
                    {
                        removalList.Add(i);
                    }

                    if (onBlankLine)
                    {
                        done = true;
                    }
                    else
                    {
                        onBlankLine = true;
                    }

                    break;

                default:
                    done = true;
                    break;
                }

                if (done)
                {
                    break;
                }
            }

            // Remove copyright lines in reverse order.
            for (int i = removalList.Count - 1; i >= 0; i--)
            {
                trivia = trivia.RemoveAt(removalList[i]);
            }

            string newLineText = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
            var newLineTrivia = SyntaxFactory.EndOfLine(newLineText);

            var newHeaderTrivia = CreateNewHeader(leadingSpaces + "//", document.Name, settings, newLineText);
            if (!isMalformedHeader && copyrightTriviaIndex.HasValue)
            {
                // Does the copyright element have leading whitespace? If so remove it.
                if ((copyrightTriviaIndex.Value > 0) && trivia[copyrightTriviaIndex.Value - 1].IsKind(SyntaxKind.WhitespaceTrivia))
                {
                    copyrightTriviaIndex = copyrightTriviaIndex - 1;
                    trivia = trivia.RemoveAt(copyrightTriviaIndex.Value);
                }

                // Replace copyright element in place.
                return root.WithLeadingTrivia(trivia.ReplaceRange(trivia[copyrightTriviaIndex.Value], newHeaderTrivia));
            }
            else
            {
                // Add blank line if we don't already have comments at top of file.
                if (!FirstLineIsComment(trivia))
                {
                    newHeaderTrivia = newHeaderTrivia.Add(newLineTrivia);
                }

                // Insert header at top of the file.
                return root.WithLeadingTrivia(newHeaderTrivia.Add(newLineTrivia).AddRange(trivia));
            }
        }
        private static void HandleCompilationUnit(SyntaxNodeAnalysisContext context, StyleCopSettings settings)
        {
            var elementOrder = settings.OrderingRules.ElementOrder;
            int accessibilityIndex = elementOrder.IndexOf(OrderingTrait.Accessibility);
            if (accessibilityIndex < 0)
            {
                return;
            }

            var compilationUnit = (CompilationUnitSyntax)context.Node;

            HandleMemberList(context, elementOrder, accessibilityIndex, compilationUnit.Members, AccessLevel.Internal);
        }
 private static SyntaxTriviaList CreateNewHeader(string prefixWithLeadingSpaces, string filename, StyleCopSettings settings, string newLineText)
 {
     var copyrightText = prefixWithLeadingSpaces + " " + GetCopyrightText(prefixWithLeadingSpaces, settings.DocumentationRules.CopyrightText, newLineText);
     var newHeader = settings.DocumentationRules.XmlHeader
         ? WrapInXmlComment(prefixWithLeadingSpaces, copyrightText, filename, settings, newLineText)
         : copyrightText;
     return SyntaxFactory.ParseLeadingTrivia(newHeader);
 }
        private static bool CompareCopyrightText(string copyrightText, StyleCopSettings settings)
        {
            // make sure that both \n and \r\n are accepted from the settings.
            var reformattedCopyrightTextParts = settings.DocumentationRules.CopyrightText.Replace("\r\n", "\n").Split('\n');
            var fileHeaderCopyrightTextParts = copyrightText.Replace("\r\n", "\n").Split('\n');

            if (reformattedCopyrightTextParts.Length != fileHeaderCopyrightTextParts.Length)
            {
                return false;
            }

            // compare line by line, ignoring leading and trailing whitespace on each line.
            for (var i = 0; i < reformattedCopyrightTextParts.Length; i++)
            {
                if (string.CompareOrdinal(reformattedCopyrightTextParts[i].Trim(), fileHeaderCopyrightTextParts[i].Trim()) != 0)
                {
                    return false;
                }
            }

            return true;
        }
        private static SyntaxNode ReplaceWellFormedMultiLineCommentHeader(Document document, SyntaxNode root, StyleCopSettings settings, int commentIndex, XmlFileHeader header)
        {
            SyntaxTriviaList trivia = root.GetLeadingTrivia();
            var commentTrivia = trivia[commentIndex];

            // Is the comment pushed in by a prefix?
            var commentIndentation = string.Empty;
            if (commentIndex > 0)
            {
                var prefixTrivia = trivia[commentIndex - 1];
                if (prefixTrivia.IsKind(SyntaxKind.WhitespaceTrivia))
                {
                    commentIndentation = prefixTrivia.ToFullString();
                }
            }

            var triviaString = commentTrivia.ToFullString();
            var startIndex = triviaString.IndexOf("/*", StringComparison.Ordinal) + 2;
            var endIndex = triviaString.LastIndexOf("*/", StringComparison.Ordinal);
            var commentContext = triviaString.Substring(startIndex, endIndex - startIndex).Trim(' ', '\t').TrimEnd();
            var triviaStringParts = commentContext.Replace("\r\n", "\n").Split('\n');

            // Assume we have comments that have a leading *
            string interlinePadding = " *";

            int minExpectedLength = (commentIndentation + interlinePadding).Length;
            string newLineText = document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);

            // Examine second line to see if we should have stars or not if it's blank
            // set the interline padding to be blank also.
            if ((triviaStringParts.Length > 2) &&
                (triviaStringParts[1].Length > minExpectedLength) &&
                string.IsNullOrWhiteSpace(triviaStringParts[1].Substring(0, minExpectedLength)))
            {
                interlinePadding = "  ";
            }

            // Pad line that used to be next to a /*
            triviaStringParts[0] = commentIndentation + interlinePadding + " " + triviaStringParts[0];
            StringBuilder sb = StringBuilderPool.Allocate();
            var copyrightText = commentIndentation + interlinePadding + " " +
                GetCopyrightText(commentIndentation + interlinePadding, settings.DocumentationRules.CopyrightText, newLineText);
            var newHeader = WrapInXmlComment(commentIndentation + interlinePadding, copyrightText, document.Name, settings, newLineText);

            sb.Append(commentIndentation);
            sb.Append("/*");
            if (header.GetElement("copyright") == null)
            {
                // No copyright element at the moment so add us.
                sb.Append(newHeader.Substring(minExpectedLength));
                sb.Append(newLineText);

                // Append the original stuff
                foreach (var oldLine in triviaStringParts)
                {
                    sb.Append(oldLine.TrimEnd());
                    sb.Append(newLineText);
                }
            }
            else
            {
                bool firstLine = true;
                bool inCopyright = false;
                foreach (var oldLine in triviaStringParts)
                {
                    var openingTag = oldLine.Contains("<copyright ");
                    var closingTag = oldLine.Contains("</copyright>") ||
                        (openingTag && oldLine.Trim().EndsWith("/>"));
                    if (openingTag)
                    {
                        inCopyright = !closingTag;
                        sb.Append(newHeader.Substring(firstLine ? minExpectedLength : 0));
                        sb.Append(newLineText);
                    }

                    if (inCopyright)
                    {
                        inCopyright = !closingTag;
                    }
                    else
                    {
                        sb.Append(oldLine.Substring(firstLine ? minExpectedLength : 0));
                        sb.Append(newLineText);
                    }

                    firstLine = false;
                }
            }

            sb.Append(commentIndentation);
            sb.Append(" */");

            // Get rid of any trailing spaces.
            var lines = sb.ToString().Split(new string[] { newLineText }, StringSplitOptions.None);
            sb.Clear();
            for (int i = 0; i < lines.Length; i++)
            {
                sb.Append((i == 0 ? string.Empty : newLineText) + lines[i].TrimEnd());
            }

            var newTrivia = SyntaxFactory.SyntaxTrivia(SyntaxKind.MultiLineCommentTrivia, StringBuilderPool.ReturnAndFree(sb));
            return root.WithLeadingTrivia(trivia.Replace(commentTrivia, newTrivia));
        }
Exemplo n.º 30
0
            public static void HandleSyntaxTree(SyntaxTreeAnalysisContext context, StyleCopSettings settings, Compilation compilation)
            {
                var root = context.Tree.GetRoot(context.CancellationToken);

                // don't process empty files
                if (root.FullSpan.IsEmpty)
                {
                    return;
                }

                if (settings.DocumentationRules.XmlHeader)
                {
                    var fileHeader = FileHeaderHelpers.ParseXmlFileHeader(root);
                    if (fileHeader.IsMissing)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(SA1633DescriptorMissing, fileHeader.GetLocation(context.Tree)));
                        return;
                    }

                    if (fileHeader.IsMalformed)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(SA1633DescriptorMalformed, fileHeader.GetLocation(context.Tree)));
                        return;
                    }

                    if (!compilation.IsAnalyzerSuppressed(SA1634Identifier))
                    {
                        CheckCopyrightHeader(context, settings.DocumentationRules, compilation, fileHeader);
                    }

                    if (!compilation.IsAnalyzerSuppressed(SA1639Identifier))
                    {
                        CheckSummaryHeader(context, compilation, fileHeader);
                    }
                }
                else
                {
                    var fileHeader = FileHeaderHelpers.ParseFileHeader(root);
                    if (fileHeader.IsMissing)
                    {
                        context.ReportDiagnostic(Diagnostic.Create(SA1633DescriptorMissing, fileHeader.GetLocation(context.Tree)));
                        return;
                    }

                    if (!compilation.IsAnalyzerSuppressed(SA1635Identifier))
                    {
                        if (string.IsNullOrWhiteSpace(fileHeader.CopyrightText))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(SA1635Descriptor, fileHeader.GetLocation(context.Tree)));
                            return;
                        }

                        if (compilation.IsAnalyzerSuppressed(SA1636Identifier))
                        {
                            return;
                        }

                        if (!CompareCopyrightText(settings.DocumentationRules, fileHeader.CopyrightText))
                        {
                            context.ReportDiagnostic(Diagnostic.Create(SA1636Descriptor, fileHeader.GetLocation(context.Tree)));
                            return;
                        }
                    }
                }
            }