Exemple #1
0
        public static Task <Document> AddNewLineBeforeInsteadOfAfterAsync(
            Document document,
            SyntaxNodeOrToken left,
            SyntaxNodeOrToken middle,
            SyntaxNodeOrToken right,
            CancellationToken cancellationToken = default)
        {
            StringBuilder sb = StringBuilderCache.GetInstance();

            SyntaxTriviaList trailingTrivia = middle.GetTrailingTrivia();

            if (IsOptionalWhitespaceThenEndOfLineTrivia(trailingTrivia))
            {
                sb.Append(DetermineEndOfLine(middle).ToString());
            }
            else
            {
                sb.Append(trailingTrivia.ToString());
            }

            sb.Append(right.GetLeadingTrivia().ToString());
            sb.Append(middle.ToString());
            sb.Append(" ");

            return(document.WithTextChangeAsync(
                       TextSpan.FromBounds(left.Span.End, right.SpanStart),
                       StringBuilderCache.GetStringAndFree(sb),
                       cancellationToken));
        }
Exemple #2
0
        public static Task <Document> AddNewLineAfterInsteadOfBeforeAsync(
            Document document,
            SyntaxNodeOrToken left,
            SyntaxNodeOrToken middle,
            SyntaxNodeOrToken right,
            CancellationToken cancellationToken = default)
        {
            StringBuilder sb = StringBuilderCache.GetInstance();

            sb.Append(" ");
            sb.Append(middle.ToString());

            SyntaxTriviaList trailingTrivia = left.GetTrailingTrivia();

            if (SyntaxTriviaAnalysis.IsOptionalWhitespaceThenEndOfLineTrivia(trailingTrivia))
            {
                sb.Append(SyntaxTriviaAnalysis.GetEndOfLine(left).ToString());
            }
            else
            {
                sb.Append(trailingTrivia.ToString());
            }

            sb.Append(middle.GetLeadingTrivia().ToString());

            string newText = StringBuilderCache.GetStringAndFree(sb);

            var textChange = new TextChange(
                TextSpan.FromBounds(left.Span.End, right.SpanStart),
                newText);

            return(document.WithTextChangeAsync(textChange, cancellationToken));
        }
Exemple #3
0
        public override SyntaxNode VisitInitializerExpression(InitializerExpressionSyntax node)
        {
            if (!node.DescendantTrivia().All(SyntaxUtils.IsWhitespace))
            {
                return(node);               // nothing to do here
            }
            if (node.IsKind(SyntaxKind.ComplexElementInitializerExpression))
            {
                return(VisitElementInitializer(node));
            }

            if (!node.IsKind(SyntaxKind.CollectionInitializerExpression) && !node.IsKind(SyntaxKind.ArrayInitializerExpression))
            {
                return(node);
            }

            var indent = node.GetIndentation();

            var exprList = node.Expressions;
            SyntaxNodeOrToken prevNode = node.OpenBraceToken;

            foreach (var nodeOrToken in exprList.GetWithSeparators())
            {
                if (nodeOrToken.IsNode && prevNode.GetTrailingTrivia().Any(SyntaxKind.EndOfLineTrivia))
                {
                    var tok = nodeOrToken.AsNode().GetFirstToken();
                    AddChange(tok, tok.WithLeadingWhitespace(indent + '\t'));
                }
                prevNode = nodeOrToken;
            }

            if (prevNode.GetTrailingTrivia().Any(SyntaxKind.EndOfLineTrivia))
            {
                AddChange(node.CloseBraceToken, node.CloseBraceToken.WithLeadingWhitespace(indent));
            }

            return(base.VisitInitializerExpression(node));
        }
Exemple #4
0
        private void AddTriviaIfAvailable(SyntaxNodeOrToken node, TreeViewItem treeNodeItem)
        {
            if (node.HasLeadingTrivia)
            {
                var trivia = node.GetLeadingTrivia()[0];
                WriteTriviaNode(treeNodeItem, trivia, "Leading Trivia - ");
            }

            if (node.HasTrailingTrivia)
            {
                var trivia = node.GetTrailingTrivia()[0];
                WriteTriviaNode(treeNodeItem, trivia, "Trailing Trivia - ");
            }
        }
        /// <summary>
        /// Search the Children of this object for an EOL Trivia after the position of the replacedNode
        /// </summary>
        /// <param name="objToSearch">The Node or Token to search the children of (and then itself) for a SyntaxKind.EndOfLineTrivia</param>
        /// <param name="endReplacedSpan">The character position at the end of the replacedNode - dont want EOLs from before the replacement</param>
        /// <param name="foundEOL">the object to get back to the top when we find it</param>
        /// <returns>True if we found  it</returns>
        bool FindEOLAfter(SyntaxNodeOrToken objToSearch, int endReplacedSpan, ref SyntaxTrivia foundEOL)
        {
            // Guard for the object is before the replacedNode
            if (objToSearch.FullSpan.End < endReplacedSpan)
            {
                return(false);
            }

            // Search each child for the trivia
            foreach (SyntaxNodeOrToken n in objToSearch.ChildNodesAndTokens())
            {
                if (n.FullSpan.End < endReplacedSpan)
                {
                    continue;
                }

                if (FindEOLAfter(n, endReplacedSpan, ref foundEOL))
                {
                    return(true);
                }
            }

            // Now search this object
            foreach (SyntaxTrivia item in objToSearch.GetLeadingTrivia())
            {
                //Dont bother if the start of the element is before the replaced Node
                if (objToSearch.FullSpan.Start < endReplacedSpan)
                {
                    continue;
                }

                if (item.Kind() == SyntaxKind.EndOfLineTrivia)
                {
                    foundEOL = item;
                    return(true);
                }
            }
            foreach (SyntaxTrivia item in objToSearch.GetTrailingTrivia())
            {
                if (item.Kind() == SyntaxKind.EndOfLineTrivia)
                {
                    foundEOL = item;
                    return(true);
                }
            }

            return(false);
        }
        static IEnumerable <(object element, ElementType type, int nestedLevel)> GetTrivia(SyntaxNodeOrToken target, int nestedLevel)
        {
            if (target.HasLeadingTrivia)
            {
                foreach (var trivia in target.GetLeadingTrivia())
                {
                    yield return(trivia, ElementType.SyntaxTrivia, nestedLevel);
                }
            }

            if (target.HasTrailingTrivia)
            {
                foreach (var trivia in target.GetTrailingTrivia())
                {
                    yield return(trivia, ElementType.SyntaxTrivia, nestedLevel);
                }
            }
        }
Exemple #7
0
        static void SeekTrivia(SyntaxNodeOrToken target, int nestedLevel)
        {
            if (target.HasLeadingTrivia)
            {
                foreach (var trivia in target.GetLeadingTrivia())
                {
                    ConsoleWrite(trivia, nestedLevel);
                }
            }

            if (target.HasTrailingTrivia)
            {
                foreach (var trivia in target.GetTrailingTrivia())
                {
                    ConsoleWrite(trivia, nestedLevel);
                }
            }
        }
Exemple #8
0
        private Nodes SyntaxNodeToNodes(SyntaxNodeOrToken s)
        {
            Nodes node = new Nodes();

            node.Kind       = s.Kind();
            node.Language   = s.Kind().ToString() + " [" + s.SpanStart + "..." + s.Span.End + "]";
            node.syntaxNode = s;

            if (s.HasLeadingTrivia)
            {
                SyntaxTriviaList d = s.GetLeadingTrivia();
                foreach (SyntaxTrivia t in d)
                {
                    Nodes tr = new Nodes();
                    tr.Language = "Leading: " + t.ToString() + " [" + t.SpanStart + "..." + t.Span.End + "]";
                    node.nodes.Add(tr);
                }
                node.IsLeadingTrivia = true;
            }
            if (s.HasTrailingTrivia)
            {
                SyntaxTriviaList d = s.GetTrailingTrivia();
                foreach (SyntaxTrivia t in d)
                {
                    Nodes tr = new Nodes();
                    tr.Language = "Trailing: " + t.ToString() + " [" + t.SpanStart + "..." + t.Span.End + "]";
                    node.nodes.Add(tr);
                }

                node.IsTrailingTrivia = true;
            }
            foreach (SyntaxNodeOrToken c in s.ChildNodesAndTokens())
            {
                Nodes ng = SyntaxNodeToNodes(c);
                node.nodes.Add(ng);
            }
            return(node);
        }
Exemple #9
0
        /// <summary>
        /// Prints full hierarchy of the specified syntax node or token as string representation.
        /// </summary>
        /// <param name="builder">The builder used to create a string representation.</param>
        /// <param name="nodeOrToken">The syntax node or token to print.</param>
        /// <param name="depth">The initial indent depth.</param>
        /// <param name="indent">The indent value used for nested nodes.</param>
        public static void PrintSyntaxNodeOrToken(StringBuilder builder, SyntaxNodeOrToken nodeOrToken, int depth = 0, int indent = 4)
        {
            if (builder == null)
            {
                throw new ArgumentNullException(nameof(builder));
            }
            if (depth < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(depth));
            }
            if (indent < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(indent));
            }

            builder.Append(' ', indent * depth);
            builder.Append($"{nodeOrToken.Kind()} {nodeOrToken.Span}");
            builder.AppendLine();

            foreach (SyntaxTrivia trivia in nodeOrToken.GetLeadingTrivia())
            {
                builder.Append(' ', indent * (depth + 1));
                builder.Append($"Lead: {trivia.Kind()} {trivia.Span}");
                builder.AppendLine();
            }

            foreach (SyntaxTrivia trivia in nodeOrToken.GetTrailingTrivia())
            {
                builder.Append(' ', indent * (depth + 1));
                builder.Append($"Trail: {trivia.Kind()} {trivia.Span}");
                builder.AppendLine();
            }

            foreach (SyntaxNodeOrToken childNodeOrToken in nodeOrToken.ChildNodesAndTokens())
            {
                PrintSyntaxNodeOrToken(builder, childNodeOrToken, depth + 1, indent);
            }
        }
        private static void Analyze <TNode>(
            SyntaxNodeAnalysisContext context,
            SyntaxNodeOrToken openNodeOrToken,
            SeparatedSyntaxList <TNode> nodes) where TNode : SyntaxNode
        {
            TNode first = nodes.FirstOrDefault();

            if (first == null)
            {
                return;
            }

            TextSpan span = nodes.GetSpan(includeExteriorTrivia: false);

            if (span.IsSingleLine(first.SyntaxTree))
            {
                SyntaxTriviaList trailing = openNodeOrToken.GetTrailingTrivia();

                if (!IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailing))
                {
                    return;
                }

                int indentationLength = GetIncreasedIndentationLength(openNodeOrToken.Parent);

                if (indentationLength == 0)
                {
                    return;
                }

                if (ShouldFixIndentation(first.GetLeadingTrivia(), indentationLength))
                {
                    ReportDiagnostic();
                }
            }
            else
            {
                TextLineCollection lines = null;

                IndentationAnalysis indentationAnalysis = IndentationAnalysis.Create(openNodeOrToken.Parent);

                int indentationLength = indentationAnalysis.IncreasedIndentationLength;

                if (indentationLength == 0)
                {
                    return;
                }

                for (int i = nodes.Count - 1; i >= 0; i--)
                {
                    SyntaxTriviaList trailing = (i == 0)
                        ? openNodeOrToken.GetTrailingTrivia()
                        : nodes.GetSeparator(i - 1).TrailingTrivia;

                    if (IsOptionalWhitespaceThenOptionalSingleLineCommentThenEndOfLineTrivia(trailing))
                    {
                        if (ShouldFixIndentation(nodes[i].GetLeadingTrivia(), indentationLength))
                        {
                            ReportDiagnostic();
                            break;
                        }
                    }
                    else
                    {
                        if (nodes.Count > 1 &&
                            ShouldWrapAndIndent(context.Node, i))
                        {
                            ReportDiagnostic();
                            break;
                        }

                        if (nodes.Count == 1 &&
                            first.IsKind(SyntaxKind.Argument))
                        {
                            var argument = (ArgumentSyntax)(SyntaxNode)first;

                            LambdaBlock lambdaBlock = GetLambdaBlock(argument, lines ??= first.SyntaxTree.GetText().Lines);

                            if (lambdaBlock.Block != null)
                            {
                                SyntaxToken      token   = lambdaBlock.Token;
                                SyntaxTriviaList leading = token.LeadingTrivia;

                                if (leading.Any())
                                {
                                    SyntaxTrivia trivia = leading.Last();

                                    if (trivia.IsWhitespaceTrivia() &&
                                        trivia.SpanStart == lambdaBlock.LineStartIndex &&
                                        trivia.Span.Length != indentationAnalysis.IndentationLength)
                                    {
                                        ReportDiagnostic();
                                        break;
                                    }
                                }
                                else if (lambdaBlock.LineStartIndex == token.SpanStart)
                                {
                                    ReportDiagnostic();
                                    break;
                                }

                                return;
                            }
                        }

                        if (lines == null)
                        {
                            lines = first.SyntaxTree.GetText().Lines;
                        }

                        int lineIndex = lines.IndexOf(span.Start);
                        if (lineIndex < lines.Count - 1)
                        {
                            int lineStartIndex = lines[lineIndex + 1].Start;

                            if (first.Span.Contains(lineStartIndex))
                            {
                                SyntaxToken token = first.FindToken(lineStartIndex);

                                if (!token.IsKind(SyntaxKind.None))
                                {
                                    SyntaxTriviaList leading = token.LeadingTrivia;

                                    if (leading.Any())
                                    {
                                        if (leading.FullSpan.Contains(lineStartIndex))
                                        {
                                            SyntaxTrivia trivia = leading.Last();

                                            if (trivia.IsWhitespaceTrivia() &&
                                                trivia.SpanStart == lineStartIndex &&
                                                trivia.Span.Length != indentationLength)
                                            {
                                                ReportDiagnostic();
                                                break;
                                            }
                                        }
                                    }
                                    else if (lineStartIndex == token.SpanStart)
                                    {
                                        ReportDiagnostic();
                                        break;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            void ReportDiagnostic()
            {
                DiagnosticHelpers.ReportDiagnostic(
                    context,
                    DiagnosticDescriptors.FixFormattingOfList,
                    Location.Create(first.SyntaxTree, nodes.Span),
                    GetTitle());
            }
Exemple #11
0
        private int GetSimilarity(SyntaxNodeOrToken node1, SyntaxNodeOrToken node2)
        {
            // count the characters in the common/identical nodes
            int w = 0;
            _nodeSimilaritySet.Clear();
            _tokenTextSimilaritySet.Clear();

            if (node1.IsToken && node2.IsToken)
            {
                var text1 = node1.ToString();
                var text2 = node2.ToString();

                if (text1 == text2)
                {
                    // main text of token is the same
                    w += text1.Length;
                }

                foreach (var tr in node1.GetLeadingTrivia())
                {
                    _nodeSimilaritySet.Add(tr.UnderlyingNode);
                }

                foreach (var tr in node1.GetTrailingTrivia())
                {
                    _nodeSimilaritySet.Add(tr.UnderlyingNode);
                }

                foreach (var tr in node2.GetLeadingTrivia())
                {
                    if (_nodeSimilaritySet.Contains(tr.UnderlyingNode))
                    {
                        w += tr.FullSpan.Length;
                    }
                }

                foreach (var tr in node2.GetTrailingTrivia())
                {
                    if (_nodeSimilaritySet.Contains(tr.UnderlyingNode))
                    {
                        w += tr.FullSpan.Length;
                    }
                }
            }
            else
            {
                foreach (var n1 in node1.ChildNodesAndTokens())
                {
                    _nodeSimilaritySet.Add(n1.UnderlyingNode);

                    if (n1.IsToken)
                    {
                        _tokenTextSimilaritySet.Add(n1.ToString());
                    }
                }

                foreach (var n2 in node2.ChildNodesAndTokens())
                {
                    if (_nodeSimilaritySet.Contains(n2.UnderlyingNode))
                    {
                        w += n2.FullSpan.Length;
                    }
                    else if (n2.IsToken)
                    {
                        var tokenText = n2.ToString();
                        if (_tokenTextSimilaritySet.Contains(tokenText))
                        {
                            w += tokenText.Length;
                        }
                    }
                }
            }

            return w;
        }