示例#1
0
        private void DoTestAddInsertRemoveReplaceOnEmptyList(SyntaxTriviaList list)
        {
            Assert.Equal(0, list.Count);

            var triviaD = SyntaxFactory.ParseLeadingTrivia("/*D*/")[0];
            var triviaE = SyntaxFactory.ParseLeadingTrivia("/*E*/")[0];

            var newList = list.Add(triviaD);

            Assert.Equal(1, newList.Count);
            Assert.Equal("/*D*/", newList.ToFullString());

            newList = list.AddRange(new[] { triviaD, triviaE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("/*D*//*E*/", newList.ToFullString());

            newList = list.Insert(0, triviaD);
            Assert.Equal(1, newList.Count);
            Assert.Equal("/*D*/", newList.ToFullString());

            newList = list.InsertRange(0, new[] { triviaD, triviaE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("/*D*//*E*/", newList.ToFullString());

            newList = list.Remove(triviaD);
            Assert.Equal(0, newList.Count);

            Assert.Equal(-1, list.IndexOf(triviaD));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.RemoveAt(0));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(1, triviaD));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(-1, triviaD));
            Assert.Throws <ArgumentOutOfRangeException>(
                () => list.InsertRange(1, new[] { triviaD })
                );
            Assert.Throws <ArgumentOutOfRangeException>(
                () => list.InsertRange(-1, new[] { triviaD })
                );
            Assert.Throws <ArgumentOutOfRangeException>(() => list.Replace(triviaD, triviaE));
            Assert.Throws <ArgumentOutOfRangeException>(
                () => list.ReplaceRange(triviaD, new[] { triviaE })
                );
            Assert.Throws <ArgumentOutOfRangeException>(() => list.Add(default(SyntaxTrivia)));
            Assert.Throws <ArgumentOutOfRangeException>(() => list.Insert(0, default(SyntaxTrivia)));
            Assert.Throws <ArgumentNullException>(
                () => list.AddRange((IEnumerable <SyntaxTrivia>)null)
                );
            Assert.Throws <ArgumentNullException>(
                () => list.InsertRange(0, (IEnumerable <SyntaxTrivia>)null)
                );
        }
示例#2
0
 private static void InsertIfNotWhiteSpaceOrEndOfLine(IEnumerable <SyntaxTrivia> trivia, ref SyntaxTriviaList triviaList)
 {
     if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia()))
     {
         triviaList = triviaList.InsertRange(0, trivia);
     }
 }
示例#3
0
        /// <summary>
        /// Ensure the trivia list has a blank line at the end.  Both the second to last
        /// and final line may contain spaces.
        ///
        /// Note: This function assumes the trivia token before <param name="startIndex" />
        /// is an end of line trivia.
        /// </summary>
        private static void EnsureHasBlankLineAtEnd(ref SyntaxTriviaList list, int startIndex, SyntaxTrivia newLineTrivia)
        {
            const int StateNone      = 0;
            const int StateEol       = 1;
            const int StateBlankLine = 2;

            var state    = StateEol;
            var index    = startIndex;
            var eolIndex = startIndex - 1;

            while (index < list.Count)
            {
                var current = list[index];
                if (current.IsKind(SyntaxKind.WhitespaceTrivia))
                {
                    index++;
                    continue;
                }

                var isStateAnyEol = (state == StateEol || state == StateBlankLine);
                if (isStateAnyEol && current.IsKind(SyntaxKind.EndOfLineTrivia))
                {
                    state = StateBlankLine;
                }
                else if (current.IsAnyEndOfLine())
                {
                    eolIndex = index;
                    state    = StateEol;
                }
                else
                {
                    state = StateNone;
                }

                index++;
            }

            switch (state)
            {
            case StateNone:
                list = list.InsertRange(list.Count, new[] { newLineTrivia, newLineTrivia });
                break;

            case StateEol:
                list = list.Insert(eolIndex + 1, newLineTrivia);
                break;

            case StateBlankLine:
                // Nothing to do.
                break;

            default:
                Debug.Assert(false);
                break;
            }
        }
示例#4
0
            public override SyntaxTriviaList VisitList(SyntaxTriviaList list)
            {
                var index = list.IndexOf(_originalTrivia);

                if (index >= 0 && index < list.Count)
                {
                    switch (editKind)
                    {
                    case ListEditKind.Replace:
                        return(list.ReplaceRange(_originalTrivia, _newTrivia));

                    case ListEditKind.InsertAfter:
                        return(list.InsertRange(index + 1, _newTrivia));

                    case ListEditKind.InsertBefore:
                        return(list.InsertRange(index, _newTrivia));
                    }
                }

                return(base.VisitList(list));
            }
        public static async Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax left          = binaryExpression.Left;
            ExpressionSyntax right         = binaryExpression.Right;
            SyntaxToken      operatorToken = binaryExpression.OperatorToken;

            ExpressionSyntax newNode = binaryExpression;

            TextSpan span = TextSpan.FromBounds(left.Span.End, right.Span.Start);

            IEnumerable <SyntaxTrivia> trivia = binaryExpression.DescendantTrivia(span);

            bool isWhiteSpaceOrEndOfLine = trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia());

            if (left.IsBooleanLiteralExpression())
            {
                SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    leadingTrivia = leadingTrivia.AddRange(trivia);
                }

                newNode = right
                          .Negate()
                          .WithLeadingTrivia(leadingTrivia);
            }
            else if (right.IsBooleanLiteralExpression())
            {
                SyntaxTriviaList trailingTrivia = binaryExpression.GetTrailingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    trailingTrivia = trailingTrivia.InsertRange(0, trivia);
                }

                newNode = left
                          .Negate()
                          .WithTrailingTrivia(trailingTrivia);
            }
#if DEBUG
            else
            {
                Debug.Assert(false, binaryExpression.ToString());
            }
#endif

            return(await document.ReplaceNodeAsync(binaryExpression, newNode.WithFormatterAnnotation(), cancellationToken).ConfigureAwait(false));
        }
示例#6
0
        public static Task <Document> RefactorAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax left  = binaryExpression.Left;
            ExpressionSyntax right = binaryExpression.Right;

            ExpressionSyntax newNode = binaryExpression;

            TextSpan span = TextSpan.FromBounds(left.Span.End, right.SpanStart);

            IEnumerable <SyntaxTrivia> trivia = binaryExpression.DescendantTrivia(span);

            bool isWhiteSpaceOrEndOfLine = trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia());

            if (IsBooleanLiteralExpression(left.Kind()))
            {
                SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    leadingTrivia = leadingTrivia.AddRange(trivia);
                }

                newNode = right.WithLeadingTrivia(leadingTrivia);
            }
            else if (IsBooleanLiteralExpression(right.Kind()))
            {
                SyntaxTriviaList trailingTrivia = binaryExpression.GetTrailingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    trailingTrivia = trailingTrivia.InsertRange(0, trivia);
                }

                newNode = left.WithTrailingTrivia(trailingTrivia);
            }
            else
            {
                SyntaxDebug.Fail(binaryExpression);
            }

            return(document.ReplaceNodeAsync(binaryExpression, newNode.WithFormatterAnnotation(), cancellationToken));
        }
示例#7
0
        /// <summary>
        /// Get new leading trivia with summary comments inserted
        /// </summary>
        /// <param name="leadingTrivias">Original leading trivia</param>
        /// <param name="summaryComments">Enumerable of summary comments</param>
        /// <param name="whitespaceCount">Whitespace count</param>
        /// <returns>new leading trivia with summary comments inserted</returns>
        public static IEnumerable <SyntaxTrivia> GetNewLeadingTriviaWithSummary(SyntaxTriviaList leadingTrivias, IEnumerable <string> summaryComments, int whitespaceCount)
        {
            var summaryTrivias = SyntaxFactory.ParseLeadingTrivia(ConcatCommentString(summaryComments, whitespaceCount));
            var index          = leadingTrivias.IndexOf(SyntaxKind.SingleLineDocumentationCommentTrivia);

            if (index == -1)
            {
                index = 0;
            }

            if (index > 0 &&
                leadingTrivias[index - 1].Kind() == SyntaxKind.WhitespaceTrivia)
            {
                index -= 1;
            }

            return(leadingTrivias.InsertRange(index, summaryTrivias));
        }
示例#8
0
        public static MemberDeclarationSyntax GenerateAndAttach(MemberDeclarationSyntax memberDeclaration, DocumentationCommentGeneratorSettings settings = null)
        {
            if (memberDeclaration == null)
            {
                throw new ArgumentNullException(nameof(memberDeclaration));
            }

            SyntaxTriviaList leadingTrivia = memberDeclaration.GetLeadingTrivia();

            int index = 0;

            string indent = "";

            if (leadingTrivia.Any())
            {
                index = leadingTrivia.Count - 1;

                for (int i = leadingTrivia.Count - 1; i >= 0; i--)
                {
                    if (leadingTrivia[i].IsWhitespaceTrivia())
                    {
                        index = i;
                    }
                    else
                    {
                        break;
                    }
                }

                indent = string.Concat(leadingTrivia.Skip(index));
            }

            settings = settings ?? DocumentationCommentGeneratorSettings.Default;

            settings = settings.WithIndent(indent);

            SyntaxTriviaList comment = Generate(memberDeclaration, settings);

            SyntaxTriviaList newLeadingTrivia = leadingTrivia.InsertRange(index, comment);

            return(memberDeclaration.WithLeadingTrivia(newLeadingTrivia));
        }
示例#9
0
        public static Task <Document> RefactorAsync(
            Document document,
            InvocationExpressionSyntax invocation,
            CancellationToken cancellationToken)
        {
            var memberAccess = (MemberAccessExpressionSyntax)invocation.Expression;

            var invocation2 = (InvocationExpressionSyntax)memberAccess.Expression;

            var memberAccess2 = (MemberAccessExpressionSyntax)invocation2.Expression;

            ExpressionSyntax expression1 = GetCondition(invocation);
            ExpressionSyntax expression2 = GetCondition(invocation2);

            InvocationExpressionSyntax newInvocation = invocation2.ReplaceNode(
                expression2,
                LogicalAndExpression(
                    expression2.Parenthesize().WithSimplifierAnnotation(),
                    expression1.Parenthesize().WithSimplifierAnnotation()));

            var newMemberAccess = (MemberAccessExpressionSyntax)newInvocation.Expression;

            SyntaxTriviaList trailingTrivia = invocation.GetTrailingTrivia();

            IEnumerable <SyntaxTrivia> trivia = invocation.DescendantTrivia(TextSpan.FromBounds(invocation2.Span.End, memberAccess.Name.SpanStart));

            if (trivia.Any(f => !f.IsWhitespaceOrEndOfLineTrivia()))
            {
                trailingTrivia = trailingTrivia.InsertRange(0, trivia);
            }

            newInvocation = newInvocation
                            .WithExpression(newMemberAccess)
                            .WithTrailingTrivia(trailingTrivia)
                            .WithFormatterAnnotation();

            return(document.ReplaceNodeAsync(invocation, newInvocation, cancellationToken));
        }
        private static XmlElementSyntax TrimWhitespaceContent(XmlElementSyntax paragraph, out SyntaxList <XmlNodeSyntax> leadingWhitespaceContent, out SyntaxList <XmlNodeSyntax> trailingWhitespaceContent)
        {
            SyntaxList <XmlNodeSyntax> completeContent = XmlSyntaxFactory.List(paragraph.Content.SelectMany(ExpandTextNodes).ToArray());

            leadingWhitespaceContent  = XmlSyntaxFactory.List(completeContent.TakeWhile(x => XmlCommentHelper.IsConsideredEmpty(x)).ToArray());
            trailingWhitespaceContent = XmlSyntaxFactory.List(completeContent.Skip(leadingWhitespaceContent.Count).Reverse().TakeWhile(x => XmlCommentHelper.IsConsideredEmpty(x)).Reverse().ToArray());

            SyntaxList <XmlNodeSyntax> trimmedContent = XmlSyntaxFactory.List(completeContent.Skip(leadingWhitespaceContent.Count).Take(completeContent.Count - leadingWhitespaceContent.Count - trailingWhitespaceContent.Count).ToArray());
            SyntaxTriviaList           leadingTrivia  = SyntaxFactory.TriviaList();
            SyntaxTriviaList           trailingTrivia = SyntaxFactory.TriviaList();

            if (trimmedContent.Any())
            {
                leadingTrivia  = trimmedContent[0].GetLeadingTrivia();
                trailingTrivia = trimmedContent.Last().GetTrailingTrivia();
                trimmedContent = trimmedContent.Replace(trimmedContent[0], trimmedContent[0].WithoutLeadingTrivia());
                trimmedContent = trimmedContent.Replace(trimmedContent.Last(), trimmedContent.Last().WithoutTrailingTrivia());
            }
            else
            {
                leadingTrivia  = SyntaxFactory.TriviaList();
                trailingTrivia = SyntaxFactory.TriviaList();
            }

            XmlElementSyntax result = paragraph;

            if (leadingWhitespaceContent.Any())
            {
                var first    = leadingWhitespaceContent[0];
                var newFirst = first.WithLeadingTrivia(first.GetLeadingTrivia().InsertRange(0, paragraph.GetLeadingTrivia()));
                leadingWhitespaceContent = leadingWhitespaceContent.Replace(first, newFirst);
            }
            else
            {
                leadingTrivia = leadingTrivia.InsertRange(0, result.GetLeadingTrivia());
            }

            if (trailingWhitespaceContent.Any())
            {
                var last    = trailingWhitespaceContent.Last();
                var newLast = last.WithLeadingTrivia(last.GetLeadingTrivia().AddRange(paragraph.GetTrailingTrivia()));
                trailingWhitespaceContent = trailingWhitespaceContent.Replace(last, newLast);
            }
            else
            {
                trailingTrivia = trailingTrivia.AddRange(result.GetTrailingTrivia());
            }

            if (trimmedContent.FirstOrDefault() is XmlTextSyntax firstTextNode &&
                firstTextNode.TextTokens.Any())
            {
                SyntaxToken firstTextToken    = firstTextNode.TextTokens[0];
                string      leadingWhitespace = new(firstTextToken.Text.Cast <char>().TakeWhile(char.IsWhiteSpace).ToArray());
                if (leadingWhitespace.Length > 0)
                {
                    SyntaxToken   newFirstTextToken = XmlSyntaxFactory.TextLiteral(firstTextToken.Text.Substring(leadingWhitespace.Length)).WithTriviaFrom(firstTextToken);
                    XmlTextSyntax newFirstTextNode  = firstTextNode.WithTextTokens(firstTextNode.TextTokens.Replace(firstTextToken, newFirstTextToken));
                    trimmedContent = trimmedContent.Replace(firstTextNode, newFirstTextNode);
                    leadingTrivia  = leadingTrivia.Add(SyntaxFactory.Whitespace(leadingWhitespace));
                }
            }

            if (trimmedContent.LastOrDefault() is XmlTextSyntax lastTextNode &&
                lastTextNode.TextTokens.Any())
            {
                SyntaxToken lastTextToken      = lastTextNode.TextTokens.Last();
                string      trailingWhitespace = new(lastTextToken.Text.Cast <char>().Reverse().TakeWhile(char.IsWhiteSpace).Reverse().ToArray());
                if (trailingWhitespace.Length > 0)
                {
                    SyntaxToken   newLastTextToken = XmlSyntaxFactory.TextLiteral(lastTextToken.Text.Substring(0, lastTextToken.Text.Length - trailingWhitespace.Length)).WithTriviaFrom(lastTextToken);
                    XmlTextSyntax newLastTextNode  = lastTextNode.WithTextTokens(lastTextNode.TextTokens.Replace(lastTextToken, newLastTextToken));
                    trimmedContent = trimmedContent.Replace(lastTextNode, newLastTextNode);
                    trailingTrivia = trailingTrivia.Insert(0, SyntaxFactory.Whitespace(trailingWhitespace));
                }
            }

            return(result.WithContent(trimmedContent)
                   .WithLeadingTrivia(leadingTrivia)
                   .WithTrailingTrivia(trailingTrivia));
        }
示例#11
0
        private void DoTestAddInsertRemoveReplaceOnEmptyList(SyntaxTriviaList list)
        {
            Assert.Equal(0, list.Count);

            var triviaD = SyntaxFactory.ParseLeadingTrivia("/*D*/")[0];
            var triviaE = SyntaxFactory.ParseLeadingTrivia("/*E*/")[0];

            var newList = list.Add(triviaD);
            Assert.Equal(1, newList.Count);
            Assert.Equal("/*D*/", newList.ToFullString());

            newList = list.AddRange(new[] { triviaD, triviaE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("/*D*//*E*/", newList.ToFullString());

            newList = list.Insert(0, triviaD);
            Assert.Equal(1, newList.Count);
            Assert.Equal("/*D*/", newList.ToFullString());

            newList = list.InsertRange(0, new[] { triviaD, triviaE });
            Assert.Equal(2, newList.Count);
            Assert.Equal("/*D*//*E*/", newList.ToFullString());

            newList = list.Remove(triviaD);
            Assert.Equal(0, newList.Count);

            Assert.Equal(-1, list.IndexOf(triviaD));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.RemoveAt(0));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(1, triviaD));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.Insert(-1, triviaD));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(1, new[] { triviaD }));
            Assert.Throws<ArgumentOutOfRangeException>(() => list.InsertRange(-1, new[] { triviaD }));
            Assert.Throws<ArgumentException>(() => list.Replace(triviaD, triviaE));
            Assert.Throws<ArgumentException>(() => list.ReplaceRange(triviaD, new[] { triviaE }));
            Assert.Throws<ArgumentException>(() => list.Add(default(SyntaxTrivia)));
            Assert.Throws<ArgumentException>(() => list.Insert(0, default(SyntaxTrivia)));
            Assert.Throws<ArgumentNullException>(() => list.AddRange((IEnumerable<SyntaxTrivia>)null));
            Assert.Throws<ArgumentNullException>(() => list.InsertRange(0, (IEnumerable<SyntaxTrivia>)null));
        }
示例#12
0
        /// <summary>
        /// Get new leading trivia with doxygen comments inserted
        /// </summary>
        /// <param name="leadingTrivias">Original leading trivia</param>
        /// <param name="doxygenComments">Enumerable of doxygen comments</param>
        /// <param name="whitespaceCount">Whitespace count</param>
        /// <returns>new leading trivia with doxygen comments inserted</returns>
        public static SyntaxTriviaList GetNewLeadingTrivia(SyntaxTriviaList leadingTrivias, IEnumerable <string> doxygenComments, int whitespaceCount)
        {
            var commentTrivias = SyntaxFactory.ParseLeadingTrivia(ConcatCommentString(doxygenComments, whitespaceCount));

            return(leadingTrivias.InsertRange(leadingTrivias.Count - 1, commentTrivias));
        }
        private static async Task <ExpressionSyntax> CreateNewNodeAsync(
            Document document,
            BinaryExpressionSyntax binaryExpression,
            CancellationToken cancellationToken)
        {
            ExpressionSyntax left  = binaryExpression.Left;
            ExpressionSyntax right = binaryExpression.Right;

            TextSpan span = TextSpan.FromBounds(left.Span.End, right.Span.Start);

            IEnumerable <SyntaxTrivia> trivia = binaryExpression.DescendantTrivia(span);

            bool isWhiteSpaceOrEndOfLine = trivia.All(f => f.IsWhitespaceOrEndOfLineTrivia());

            SemanticModel semanticModel = await document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            if (left.Kind().IsBooleanLiteralExpression())
            {
                SyntaxTriviaList leadingTrivia = binaryExpression.GetLeadingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    leadingTrivia = leadingTrivia.AddRange(trivia);
                }

                if (right.IsKind(SyntaxKind.LogicalNotExpression))
                {
                    var logicalNot = (PrefixUnaryExpressionSyntax)right;

                    ExpressionSyntax operand = logicalNot.Operand;

                    if (semanticModel.GetTypeInfo(operand, cancellationToken).ConvertedType.IsNullableOf(SpecialType.System_Boolean))
                    {
                        return(binaryExpression
                               .WithLeft(LogicalNegationHelper.LogicallyNegate(left, semanticModel, cancellationToken))
                               .WithRight(operand.WithTriviaFrom(right)));
                    }
                }

                return(LogicalNegationHelper.LogicallyNegate(right, semanticModel, cancellationToken)
                       .WithLeadingTrivia(leadingTrivia));
            }
            else if (right.Kind().IsBooleanLiteralExpression())
            {
                SyntaxTriviaList trailingTrivia = binaryExpression.GetTrailingTrivia();

                if (!isWhiteSpaceOrEndOfLine)
                {
                    trailingTrivia = trailingTrivia.InsertRange(0, trivia);
                }

                if (left.IsKind(SyntaxKind.LogicalNotExpression))
                {
                    var logicalNot = (PrefixUnaryExpressionSyntax)left;

                    ExpressionSyntax operand = logicalNot.Operand;

                    if (semanticModel.GetTypeInfo(operand, cancellationToken).ConvertedType.IsNullableOf(SpecialType.System_Boolean))
                    {
                        return(binaryExpression
                               .WithLeft(operand.WithTriviaFrom(left))
                               .WithRight(LogicalNegationHelper.LogicallyNegate(right, semanticModel, cancellationToken)));
                    }
                }

                return(LogicalNegationHelper.LogicallyNegate(left, semanticModel, cancellationToken)
                       .WithTrailingTrivia(trailingTrivia));
            }

            Debug.Fail(binaryExpression.ToString());

            return(binaryExpression);
        }