Exemple #1
0
        public static SyntaxTriviaList RemoveIfDef(SyntaxTriviaList trivia)
        {
            int inDirective = 0;

            for (int i = 0; i < trivia.Count; i++)
            {
                if (trivia[i].Kind() == SyntaxKind.IfDirectiveTrivia)
                {
                    trivia = trivia.RemoveAt(i);
                    i--;
                    inDirective++;
                }
                else if (trivia[i].Kind() == SyntaxKind.EndIfDirectiveTrivia)
                {
                    trivia = trivia.RemoveAt(i);
                    i--;
                    inDirective--;
                }
                else if (inDirective > 0)
                {
                    trivia = trivia.RemoveAt(i);
                    i--;
                }
            }
            return(trivia);
        }
Exemple #2
0
        private static SyntaxTriviaList RemoveTriviaAtIndex(SyntaxTriviaList newTrivia, int index)
        {
            // Remove trivia
            newTrivia = newTrivia.RemoveAt(index);

            // Remove end of line after trivia
            if (index < newTrivia.Count && newTrivia.ElementAt(index).Kind() == SyntaxKind.EndOfLineTrivia)
            {
                newTrivia = newTrivia.RemoveAt(index);
            }

            return(newTrivia);
        }
        private static SyntaxTriviaList RemoveHeaderDecorationLines(SyntaxTriviaList trivia, StyleCopSettings settings)
        {
            if (!string.IsNullOrEmpty(settings.DocumentationRules.HeaderDecoration))
            {
                var decorationRemovalList = new List <int>();
                for (int i = 0; i < trivia.Count; i++)
                {
                    var triviaLine = trivia[i];
                    if (triviaLine.IsKind(SyntaxKind.SingleLineCommentTrivia) && triviaLine.ToFullString().Contains(settings.DocumentationRules.HeaderDecoration))
                    {
                        decorationRemovalList.Add(i);

                        // also remove the line break
                        if (i + 1 < trivia.Count && trivia[i + 1].IsKind(SyntaxKind.EndOfLineTrivia))
                        {
                            decorationRemovalList.Add(i + 1);
                        }
                    }
                }

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

            return(trivia);
        }
Exemple #4
0
        /// <summary>
        /// Determines how many type parameters of the <see cref="OriginalDeclaration"/> should the <see cref="CurrentDeclaration"/> have.
        /// </summary>
        /// <param name="count">Number of type parameters to take.</param>
        public void WithTypeParameters(int count)
        {
            if (DefaultParamUtilities.TryUpdateTypeParameters(CurrentDeclaration.TypeParameterList, count, out TypeParameterListSyntax? updated))
            {
                CurrentDeclaration = CurrentDeclaration.WithTypeParameterList(updated);
            }

            CheckDirectCall(count);
            SyntaxTokenList modifiers = CurrentDeclaration.Modifiers;

            if (!modifiers.Any())
            {
                SyntaxTriviaList trivia = CurrentDeclaration.ReturnType.GetLeadingTrivia();

                if (trivia.Any())
                {
                    trivia             = trivia.RemoveAt(trivia.Count - 1);
                    CurrentDeclaration = CurrentDeclaration.WithReturnType(CurrentDeclaration.ReturnType.WithLeadingTrivia(trivia));
                }
            }

            if (DefaultParamUtilities.TryAddNewModifier(_newModifierIndexes, count, _numNonDefaultParam, ref modifiers))
            {
                CurrentDeclaration = CurrentDeclaration.WithModifiers(modifiers);
            }
        }
        /// <summary>
        /// Determines how many type parameters of the <see cref="OriginalDeclaration"/> should the <see cref="CurrentDeclaration"/> have.
        /// </summary>
        /// <param name="count">Number of type parameters to take.</param>
        public void WithTypeParameters(int count)
        {
            if (DefaultParamUtilities.TryUpdateTypeParameters(CurrentDeclaration.TypeParameterList, count, out TypeParameterListSyntax? updated))
            {
                CurrentDeclaration = CurrentDeclaration.WithTypeParameterList(updated);
            }

            SyntaxTokenList modifiers = CurrentDeclaration.Modifiers;

            if (!modifiers.Any())
            {
                SyntaxTriviaList trivia = CurrentDeclaration.DelegateKeyword.LeadingTrivia;

                if (trivia.Any())
                {
                    trivia             = trivia.RemoveAt(trivia.Count - 1);
                    CurrentDeclaration = CurrentDeclaration.WithDelegateKeyword(CurrentDeclaration.DelegateKeyword.WithLeadingTrivia(trivia));
                }
            }

            if (DefaultParamUtilities.TryAddNewModifier(_newModifierIndexes, count, _numNonDefaultParam, ref modifiers))
            {
                CurrentDeclaration = CurrentDeclaration.WithModifiers(modifiers);
            }
        }
Exemple #6
0
        private static SyntaxTriviaList RemoveTrivia(SyntaxTriviaList triviaList, int index)
        {
            int first = FindFirstTriviaToRemove(triviaList, index);
            int last  = FindLastTriviaToRemove(triviaList, index);

            for (int i = last; i >= first; i--)
            {
                triviaList = triviaList.RemoveAt(i);
            }

            return(triviaList);
        }
Exemple #7
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)
                );
        }
Exemple #8
0
        private SyntaxNode StripLeadingLineBreak(
            SyntaxNode node,
            SyntaxToken token,
            SyntaxTriviaList trivia,
            int triviaPosition)
        {
            node = base.Visit(node);
            if (node == null)
            {
                return(null);
            }

            trivia = trivia.RemoveAt(triviaPosition);
            var newToken = token.WithLeadingTrivia(trivia);

            node = node.ReplaceToken(token, newToken);
            return(node);
        }
            static SyntaxTriviaList FlushDuplicateTrivia(
                SyntaxTriviaList trivia, int startIndex, int endIndex, bool allowExtraNewLine)
            {
                int allowedNewLines = allowExtraNewLine ? 2 : 1;
                var newLineCount = 0;
                for (; endIndex >= startIndex; endIndex--)
                {
                    if (newLineCount == allowedNewLines)
                    {
                        trivia = trivia.RemoveAt(endIndex);
                    }
                    else if (trivia[endIndex].IsKind(SyntaxKind.EndOfLineTrivia))
                    {
                        newLineCount++;
                    }
                }

                return trivia;
            }
Exemple #10
0
        private SyntaxTriviaList AlterIndent(SyntaxTriviaList leadTrivia)
        {
            var whitespaces = leadTrivia
                              .Select((trivia, i) => new
            {
                Trivia = trivia,
                Index  = i
            })
                              .Where(o => o.Trivia.IsKind(SyntaxKind.WhitespaceTrivia))
                              .ToList();

            foreach (var whitespace in whitespaces)
            {
                var trivia = whitespace.Trivia.ToFullString();
                leadTrivia = leadTrivia
                             .RemoveAt(whitespace.Index)
                             .Insert(whitespace.Index, _subtract
                                                ? Whitespace(trivia.Substring(0, Math.Max(trivia.Length - _indent.Length, 0)))
                                                : Whitespace(trivia + _indent));
            }
            return(leadTrivia);
        }
        private static void UpdateReplaceMap(Dictionary <SyntaxToken, SyntaxToken> replaceMap, SyntaxToken token, Diagnostic diagnostic)
        {
            string location;

            if (!diagnostic.Properties.TryGetValue(TokenSpacingProperties.LocationKey, out location))
            {
                return;
            }

            string action;

            if (!diagnostic.Properties.TryGetValue(TokenSpacingProperties.ActionKey, out action))
            {
                return;
            }

            string layout;

            if (!diagnostic.Properties.TryGetValue(TokenSpacingProperties.LayoutKey, out layout))
            {
                layout = TokenSpacingProperties.LayoutPack;
            }

            SyntaxTriviaList triviaList;

            switch (location)
            {
            case TokenSpacingProperties.LocationPreceding:
                var prevToken = token.GetPreviousToken();
                switch (action)
                {
                case TokenSpacingProperties.ActionInsert:
                    if (!replaceMap.ContainsKey(prevToken))
                    {
                        replaceMap[token] = token.WithLeadingTrivia(token.LeadingTrivia.Add(SyntaxFactory.Space));
                    }

                    break;

                case TokenSpacingProperties.ActionRemove:
                    bool tokenIsFirstInLine = token.IsFirstInLine();
                    bool preserveLayout     = layout == TokenSpacingProperties.LayoutPreserve;
                    triviaList = prevToken.TrailingTrivia.AddRange(token.LeadingTrivia);
                    if (triviaList.Any(t => t.IsDirective))
                    {
                        break;
                    }

                    replaceMap[prevToken] = prevToken.WithTrailingTrivia();
                    if ((!preserveLayout || !tokenIsFirstInLine) &&
                        triviaList.All(i => i.IsKind(SyntaxKind.WhitespaceTrivia) || i.IsKind(SyntaxKind.EndOfLineTrivia)))
                    {
                        replaceMap[token] = token.WithLeadingTrivia();
                    }
                    else if (tokenIsFirstInLine && token.IsLastInLine())
                    {
                        /* This block covers the case where `token` is the only non-trivia token on its line. However,
                         * the line may still contain non-whitespace trivia which we want the removal process to
                         * preserve. This code fix only removes the whitespace surrounding `token` if it is the only
                         * non-whitespace token on the line.
                         */
                        int  lastNewLineLeading    = token.LeadingTrivia.LastIndexOf(SyntaxKind.EndOfLineTrivia);
                        int  firstNewLineFollowing = token.TrailingTrivia.IndexOf(SyntaxKind.EndOfLineTrivia);
                        bool onlyWhitespace        = true;
                        for (int i = lastNewLineLeading + 1; i < token.LeadingTrivia.Count; i++)
                        {
                            onlyWhitespace &= token.LeadingTrivia[i].IsKind(SyntaxKind.WhitespaceTrivia);
                        }

                        firstNewLineFollowing = firstNewLineFollowing == -1 ? token.TrailingTrivia.Count : firstNewLineFollowing;
                        for (int i = 0; i < firstNewLineFollowing; i++)
                        {
                            onlyWhitespace &= token.TrailingTrivia[i].IsKind(SyntaxKind.WhitespaceTrivia);
                        }

                        if (onlyWhitespace)
                        {
                            // Move the token, and remove the other tokens from its line. Keep all other surrounding
                            // trivia. Keep the last newline that precedes token, but not the first that follows it.
                            SyntaxTriviaList trailingTrivia = prevToken.TrailingTrivia;
                            if (lastNewLineLeading >= 0)
                            {
                                trailingTrivia = trailingTrivia.AddRange(token.LeadingTrivia.Take(lastNewLineLeading + 1));
                            }

                            // firstNewLineFollowing was adjusted above to account for the missing case.
                            trailingTrivia = trailingTrivia.AddRange(token.TrailingTrivia.Take(firstNewLineFollowing));

                            replaceMap[token] = token.WithLeadingTrivia().WithTrailingTrivia(trailingTrivia);
                        }
                        else
                        {
                            // Just move the token and keep all surrounding trivia.
                            SyntaxTriviaList trailingTrivia = triviaList.AddRange(token.TrailingTrivia);
                            replaceMap[token] = token.WithLeadingTrivia().WithTrailingTrivia(trailingTrivia);
                        }
                    }
                    else
                    {
                        SyntaxTriviaList trailingTrivia = triviaList.AddRange(token.TrailingTrivia.WithoutLeadingWhitespace(endOfLineIsWhitespace: false));
                        replaceMap[token] = token.WithLeadingTrivia().WithTrailingTrivia(trailingTrivia);
                    }

                    break;

                case TokenSpacingProperties.ActionRemoveImmediate:
                    SyntaxTriviaList tokenLeadingTrivia = token.LeadingTrivia;
                    while (tokenLeadingTrivia.Any() && tokenLeadingTrivia.Last().IsKind(SyntaxKind.WhitespaceTrivia))
                    {
                        tokenLeadingTrivia = tokenLeadingTrivia.RemoveAt(tokenLeadingTrivia.Count - 1);
                    }

                    replaceMap[token] = token.WithLeadingTrivia(tokenLeadingTrivia);

                    if (!tokenLeadingTrivia.Any())
                    {
                        SyntaxTriviaList previousTrailingTrivia = prevToken.TrailingTrivia;
                        while (previousTrailingTrivia.Any() && previousTrailingTrivia.Last().IsKind(SyntaxKind.WhitespaceTrivia))
                        {
                            previousTrailingTrivia = previousTrailingTrivia.RemoveAt(previousTrailingTrivia.Count - 1);
                        }

                        replaceMap[prevToken] = prevToken.WithTrailingTrivia(previousTrailingTrivia);
                    }

                    break;
                }

                break;

            case TokenSpacingProperties.LocationFollowing:
                var nextToken = token.GetNextToken();
                switch (action)
                {
                case TokenSpacingProperties.ActionInsert:
                    if (!replaceMap.ContainsKey(nextToken))
                    {
                        replaceMap[token] = token.WithTrailingTrivia(token.TrailingTrivia.Insert(0, SyntaxFactory.Space));
                    }

                    break;

                case TokenSpacingProperties.ActionRemove:
                    triviaList = token.TrailingTrivia.AddRange(nextToken.LeadingTrivia);

                    replaceMap[token]     = token.WithTrailingTrivia();
                    replaceMap[nextToken] = nextToken.WithLeadingTrivia(triviaList.WithoutLeadingWhitespace(true));
                    break;
                }

                break;
            }
        }
        private static SyntaxTriviaList RemoveHeaderDecorationLines(SyntaxTriviaList trivia, StyleCopSettings settings)
        {
            if (!string.IsNullOrEmpty(settings.DocumentationRules.HeaderDecoration))
            {
                var decorationRemovalList = new List<int>();
                for (int i = 0; i < trivia.Count; i++)
                {
                    var triviaLine = trivia[i];
                    if (triviaLine.Kind() == SyntaxKind.SingleLineCommentTrivia && triviaLine.ToFullString().Contains(settings.DocumentationRules.HeaderDecoration))
                    {
                        decorationRemovalList.Add(i);

                        // also remove the line break
                        if (i + 1 < trivia.Count && trivia[i + 1].Kind() == SyntaxKind.EndOfLineTrivia)
                        {
                            decorationRemovalList.Add(i + 1);
                        }
                    }
                }

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

            return trivia;
        }
        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);
        }
Exemple #14
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);
        }
        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 List <int>();
            var    leadingSpaces         = string.Empty;
            string possibleLeadingSpaces = string.Empty;

            // remove header decoration lines, they will be re-generated
            trivia = RemoveHeaderDecorationLines(trivia, settings);

            // 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 + "//", GetFileName(document), 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--;
                    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 SyntaxTriviaList RemoveTriviaAtIndex(SyntaxTriviaList newTrivia, int index)
        {
            // Remove trivia
            newTrivia = newTrivia.RemoveAt(index);

            // Remove end of line after trivia
            if (index < newTrivia.Count && newTrivia.ElementAt(index).Kind() == SyntaxKind.EndOfLineTrivia)
            {
                newTrivia = newTrivia.RemoveAt(index);
            }

            return newTrivia;
        }
        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));
        }
Exemple #18
0
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            if (!TryFindFirstAncestorOrSelf(root, context.Span, out CompilationUnitSyntax compilationUnit))
            {
                return;
            }

            Document   document   = context.Document;
            Diagnostic diagnostic = context.Diagnostics[0];

            switch (diagnostic.Id)
            {
            case DiagnosticIdentifiers.NormalizeWhitespaceAtEndOfFile:
            {
                bool preferNewLineAtEndOfFile = document.GetConfigOptions(compilationUnit.SyntaxTree).PreferNewLineAtEndOfFile() ?? false;

                CodeAction codeAction = CodeAction.Create(
                    (preferNewLineAtEndOfFile) ? CodeFixTitles.AddNewLine : CodeFixTitles.RemoveNewLine,
                    ct =>
                    {
                        SyntaxToken endOfFile    = compilationUnit.EndOfFileToken;
                        SyntaxTriviaList leading = endOfFile.LeadingTrivia;
                        SyntaxToken oldToken;
                        SyntaxToken newToken;

                        if (!preferNewLineAtEndOfFile)
                        {
                            if (leading.Any())
                            {
                                SyntaxTrivia last = leading.Last();

                                if (last.GetStructure() is DirectiveTriviaSyntax directive)
                                {
                                    SyntaxTriviaList trailing = directive.GetTrailingTrivia();

                                    DirectiveTriviaSyntax newDirective = directive.WithTrailingTrivia(trailing.RemoveAt(trailing.Count - 1));

                                    return(document.ReplaceNodeAsync(directive, newDirective, ct));
                                }
                                else
                                {
                                    oldToken  = endOfFile;
                                    int index = leading.Count - 1;

                                    for (int i = leading.Count - 2; i >= 0; i--)
                                    {
                                        if (leading[i].IsWhitespaceOrEndOfLineTrivia())
                                        {
                                            index--;
                                        }
                                    }

                                    newToken = oldToken.WithLeadingTrivia(leading.RemoveRange(index, leading.Count - index));
                                }
                            }
                            else
                            {
                                oldToken = endOfFile.GetPreviousToken();
                                SyntaxTriviaList trailing = oldToken.TrailingTrivia;
                                newToken = oldToken.WithTrailingTrivia(trailing.RemoveAt(trailing.Count - 1));
                            }
                        }
                        else if (leading.Any())
                        {
                            oldToken = endOfFile;

                            if (leading.Span.Start == 0 &&
                                leading.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                            {
                                newToken = oldToken.WithoutLeadingTrivia();
                            }
                            else
                            {
                                newToken = oldToken.AppendEndOfLineToLeadingTrivia();
                            }
                        }
                        else
                        {
                            oldToken = endOfFile.GetPreviousToken();
                            newToken = oldToken.AppendEndOfLineToTrailingTrivia();
                        }

                        return(document.ReplaceTokenAsync(oldToken, newToken, ct));
                    },
                    GetEquivalenceKey(diagnostic));

                context.RegisterCodeFix(codeAction, diagnostic);
                break;
            }
            }
        }