private static T RemoveNode <T>(
            T declaration,
            Func <T, SyntaxList <MemberDeclarationSyntax> > getMembers,
            int index,
            SyntaxRemoveOptions removeOptions) where T : SyntaxNode
        {
            SyntaxList <MemberDeclarationSyntax> members = getMembers(declaration);

            T newDeclaration = declaration.RemoveNode(members[index], removeOptions);

            if (index == 0 &&
                index < members.Count - 1)
            {
                members = getMembers(newDeclaration);

                MemberDeclarationSyntax nextMember = members[index];

                SyntaxTriviaList leadingTrivia = nextMember.GetLeadingTrivia();

                SyntaxTrivia trivia = leadingTrivia.FirstOrDefault();

                if (trivia.IsEndOfLineTrivia())
                {
                    MemberDeclarationSyntax newNextMember = nextMember.WithLeadingTrivia(leadingTrivia.RemoveAt(0));

                    newDeclaration = newDeclaration.ReplaceNode(nextMember, newNextMember);
                }
            }

            return(newDeclaration);
        }
Example #2
0
        private static SyntaxNode RemoveNode(MemberDeclarationSyntax member)
        {
            MemberDeclarationListInfo            memberList = SyntaxInfo.MemberDeclarationListInfo(member.Parent);
            SyntaxList <MemberDeclarationSyntax> members    = memberList.Members;

            MemberDeclarationListInfo newMemberList = memberList.RemoveNode(member, SyntaxRemoveOptions.KeepUnbalancedDirectives);

            int index = members.IndexOf(member);

            if (index == 0 &&
                index < members.Count - 1)
            {
                MemberDeclarationSyntax nextMember    = newMemberList[index];
                SyntaxTriviaList        leadingTrivia = nextMember.GetLeadingTrivia();

                if (leadingTrivia.FirstOrDefault().IsEndOfLineTrivia())
                {
                    MemberDeclarationSyntax newNextMember = nextMember.WithLeadingTrivia(leadingTrivia.RemoveAt(0));

                    newMemberList = newMemberList.ReplaceNode(nextMember, newNextMember);
                }
            }

            return(newMemberList.Parent);
        }
Example #3
0
        /// <summary>
        ///Method to extract the Summary from the XML Documentation of a Property inside the SyntaxTree.
        ///To get the summary every Property must have an XML-Documentation of the form: &lt;summary&gt;&lt;/summary&gt;
        /// </summary>
        private string GetXMLSummary(SyntaxTriviaList trivias)
        {
            //Get XML-Trivia from Node
            var xmlCommentTrivia = trivias.FirstOrDefault(t => t.Kind() == SyntaxKind.SingleLineDocumentationCommentTrivia);
            var xml = xmlCommentTrivia.GetStructure();

            if (xml == null)
            {
                return("");
            }
            string xmlString = xml.ToString();
            //Get summary from XML-String
            var xmlDoc = new XmlDocument();

            xmlDoc.LoadXml(xmlString);
            XmlNodeList xnList  = xmlDoc.DocumentElement.SelectNodes("/summary");
            string      summary = xnList.Item(0).InnerText;

            //Edit Summary-String
            summary = summary.Replace("///", "");
            summary = summary.Trim();

            return(summary);
        }
        private async Task <Document> CreateChangedDocumentAsync(CodeFixContext context, DocumentationCommentTriviaSyntax documentationCommentTriviaSyntax, CancellationToken cancellationToken)
        {
            StringBuilder leadingTriviaBuilder      = new StringBuilder();
            SyntaxToken   parentToken               = documentationCommentTriviaSyntax.ParentTrivia.Token;
            int           documentationCommentIndex = parentToken.LeadingTrivia.IndexOf(documentationCommentTriviaSyntax.ParentTrivia);

            for (int i = 0; i < documentationCommentIndex; i++)
            {
                SyntaxTrivia trivia = parentToken.LeadingTrivia[i];
                switch (trivia.Kind())
                {
                case SyntaxKind.EndOfLineTrivia:
                    leadingTriviaBuilder.Clear();
                    break;

                case SyntaxKind.WhitespaceTrivia:
                    leadingTriviaBuilder.Append(trivia.ToFullString());
                    break;

                default:
                    break;
                }
            }

            leadingTriviaBuilder.Append(documentationCommentTriviaSyntax.GetLeadingTrivia().ToFullString());

            // this is the trivia that should appear at the beginning of each line of the comment.
            SyntaxTrivia leadingTrivia = SyntaxFactory.DocumentationCommentExterior(leadingTriviaBuilder.ToString());

            string newLineText   = context.Document.Project.Solution.Workspace.Options.GetOption(FormattingOptions.NewLine, LanguageNames.CSharp);
            var    semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken);

            var documentedSymbol = semanticModel.GetDeclaredSymbol(parentToken.Parent.FirstAncestorOrSelf <SyntaxNode>(SyntaxNodeExtensionsEx.IsSymbolDeclaration), context.CancellationToken);

            DocumentationCommentTriviaSyntax contentsOnly = RemoveExteriorTrivia(documentationCommentTriviaSyntax);

            contentsOnly = contentsOnly.ReplaceNodes(contentsOnly.ChildNodes(), (originalNode, rewrittenNode) => RenderBlockElementAsMarkdown(originalNode, rewrittenNode, newLineText, documentedSymbol));
            string renderedContent = contentsOnly.Content.ToFullString();

            string[] lines = renderedContent.Split(new[] { "\r\n", "\n" }, StringSplitOptions.None);
            SyntaxList <XmlNodeSyntax> newContent = XmlSyntaxFactory.List();

            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i];
                if (string.IsNullOrWhiteSpace(line))
                {
                    if (i == lines.Length - 1)
                    {
                        break;
                    }

                    line = string.Empty;
                }

                if (newContent.Count > 0)
                {
                    newContent = newContent.Add(XmlSyntaxFactory.NewLine(newLineText).WithTrailingTrivia(SyntaxFactory.DocumentationCommentExterior("///")));
                }

                newContent = newContent.Add(XmlSyntaxFactory.Text(line.TrimEnd(), xmlEscape: false));
            }

            contentsOnly = contentsOnly.WithContent(newContent);
            contentsOnly =
                contentsOnly
                .ReplaceExteriorTrivia(leadingTrivia)
                .WithLeadingTrivia(SyntaxFactory.DocumentationCommentExterior("///"))
                .WithTrailingTrivia(SyntaxFactory.EndOfLine(Environment.NewLine));

            string           fullContent         = contentsOnly.ToFullString();
            SyntaxTriviaList parsedTrivia        = SyntaxFactory.ParseLeadingTrivia(fullContent);
            SyntaxTrivia     documentationTrivia = parsedTrivia.FirstOrDefault(i => i.IsKind(SyntaxKind.SingleLineDocumentationCommentTrivia));

            contentsOnly = documentationTrivia.GetStructure() as DocumentationCommentTriviaSyntax;
            if (contentsOnly == null)
            {
                return(context.Document);
            }

            // Remove unnecessary nested paragraph elements
            contentsOnly = contentsOnly.ReplaceNodes(contentsOnly.DescendantNodes().OfType <XmlElementSyntax>(), MarkUnnecessaryParagraphs);
            contentsOnly = contentsOnly.ReplaceNodes(contentsOnly.DescendantNodes().OfType <XmlElementSyntax>(), RemoveUnnecessaryParagraphs);

            SyntaxNode root = await context.Document.GetSyntaxRootAsync(cancellationToken);

            SyntaxNode newRoot = root.ReplaceNode(documentationCommentTriviaSyntax, contentsOnly);

            if (documentationCommentTriviaSyntax.IsEquivalentTo(contentsOnly))
            {
                return(context.Document);
            }

            if (documentationCommentTriviaSyntax.ToFullString().Equals(contentsOnly.ToFullString(), StringComparison.Ordinal))
            {
                return(context.Document);
            }

            return(context.Document.WithSyntaxRoot(newRoot));
        }