private static void Analyze(
            SyntaxNodeAnalysisContext context,
            SyntaxToken token,
            SyntaxNode node)
        {
            SyntaxTriviaList trailingTrivia = token.TrailingTrivia;
            SyntaxTriviaList leadingTrivia  = node.GetLeadingTrivia();

            if (!IsStandardTriviaBetweenLines(trailingTrivia, leadingTrivia) &&
                token
                .SyntaxTree
                .GetLineSpan(TextSpan.FromBounds(token.Span.End, node.Span.Start), context.CancellationToken)
                .GetLineCount() == 3)
            {
                SyntaxTrivia trivia = leadingTrivia
                                      .SkipWhile(f => f.IsWhitespaceTrivia())
                                      .FirstOrDefault();

                if (trivia.IsEndOfLineTrivia() &&
                    trailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
                    leadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                {
                    context.ReportDiagnostic(
                        DiagnosticDescriptors.RemoveRedundantEmptyLine,
                        Location.Create(token.SyntaxTree, TextSpan.FromBounds(node.FullSpan.Start, trivia.Span.End)));
                }
            }
        }
예제 #2
0
        private static SyntaxTriviaList FormatNewlines(SyntaxTriviaList currentTrivia, SortOrder sortOrder, SortOrder?prevSortOrder)
        {
            var addNewLine = ShouldAddNewLine(sortOrder, prevSortOrder);
            var list       = currentTrivia.SkipWhile(t => t.IsKind(SyntaxKind.EndOfLineTrivia));

            if (addNewLine)
            {
                list = new[] { SyntaxFactory.CarriageReturnLineFeed }.Concat(list);
            }
            return(new SyntaxTriviaList(list));
        }
        public static void Analyze(SyntaxNodeAnalysisContext context, SwitchStatementSyntax switchStatement)
        {
            SyntaxList <SwitchSectionSyntax> sections = switchStatement.Sections;

            if (sections.Any())
            {
                AnalyzeStart(context, sections.First(), switchStatement.OpenBraceToken);
                AnalyzeEnd(context, sections.Last(), switchStatement.CloseBraceToken);

                if (sections.Count > 1)
                {
                    SwitchSectionSyntax prevSection = sections.First();

                    for (int i = 1; i < sections.Count; i++)
                    {
                        if (prevSection.Statements.LastOrDefault()?.IsKind(SyntaxKind.Block) == true)
                        {
                            SwitchSectionSyntax section = sections[i];

                            SyntaxTriviaList trailingTrivia = prevSection.GetTrailingTrivia();
                            SyntaxTriviaList leadingTrivia  = section.GetLeadingTrivia();

                            if (!IsStandardTriviaBetweenSections(trailingTrivia, leadingTrivia) &&
                                switchStatement
                                .SyntaxTree
                                .GetLineSpan(TextSpan.FromBounds(prevSection.Span.End, section.Span.Start), context.CancellationToken)
                                .GetLineCount() == 3)
                            {
                                SyntaxTrivia trivia = leadingTrivia
                                                      .SkipWhile(f => f.IsWhitespaceTrivia())
                                                      .FirstOrDefault();

                                if (trivia.IsEndOfLineTrivia() &&
                                    trailingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()) &&
                                    leadingTrivia.All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                                {
                                    context.ReportDiagnostic(
                                        DiagnosticDescriptors.RemoveRedundantEmptyLine,
                                        Location.Create(switchStatement.SyntaxTree, TextSpan.FromBounds(section.FullSpan.Start, trivia.Span.End)));
                                }
                            }
                        }

                        prevSection = sections[i];
                    }
                }
            }
        }
예제 #4
0
        private bool IsStartWithSpecialDirective(SyntaxTriviaList leadingTriviaList)
        {
            var firstDirective = leadingTriviaList.SkipWhile(x => x.IsWhitespaceTrivia()).FirstOrDefault();

            if (firstDirective == default(SyntaxTrivia))
            {
                return(false);
            }

            if (firstDirective.IsDirective)
            {
                return
                    (firstDirective.IsKind(SyntaxKind.ElseDirectiveTrivia) ||
                     firstDirective.IsKind(SyntaxKind.EndIfDirectiveTrivia));
            }
            return(false);
        }
예제 #5
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration)
        {
            VariableDeclarationSyntax declaration = localDeclaration.Declaration;

            TypeSyntax type = declaration?.Type;

            if (type?.IsVar == false)
            {
                VariableDeclaratorSyntax declarator = declaration.Variables.FirstOrDefault();

                if (declarator != null &&
                    context.Span.Start >= type.Span.Start)
                {
                    SyntaxTriviaList triviaList = type.GetTrailingTrivia();

                    if (triviaList.Any())
                    {
                        SyntaxTrivia trivia = triviaList
                                              .SkipWhile(f => f.IsKind(SyntaxKind.WhitespaceTrivia))
                                              .FirstOrDefault();

                        if (trivia.IsKind(SyntaxKind.EndOfLineTrivia) &&
                            context.Span.End <= trivia.Span.Start)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken);

                            if (typeSymbol?.IsErrorType() == false)
                            {
                                string name = Identifier.CreateName(typeSymbol, firstCharToLower: true);
                                name = Identifier.EnsureUniqueLocalName(name, declarator.SpanStart, semanticModel, context.CancellationToken);

                                if (!string.IsNullOrEmpty(name))
                                {
                                    context.RegisterRefactoring(
                                        $"Add identifier '{name}'",
                                        c => RefactorAsync(context.Document, type, name, c));
                                }
                            }
                        }
                    }
                }
            }
        }
예제 #6
0
        public static async Task ComputeRefactoringAsync(RefactoringContext context, LocalDeclarationStatementSyntax localDeclaration)
        {
            VariableDeclarationSyntax declaration = localDeclaration.Declaration;

            TypeSyntax type = declaration?.Type;

            if (type?.IsVar == false)
            {
                VariableDeclaratorSyntax declarator = declaration.Variables.FirstOrDefault();

                if (declarator != null &&
                    context.Span.Start >= type.Span.Start)
                {
                    SyntaxTriviaList triviaList = type.GetTrailingTrivia();

                    if (triviaList.Any())
                    {
                        SyntaxTrivia trivia = triviaList
                                              .SkipWhile(f => f.IsWhitespaceTrivia())
                                              .FirstOrDefault();

                        if (trivia.IsEndOfLineTrivia() &&
                            context.Span.End <= trivia.Span.Start)
                        {
                            SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                            ITypeSymbol typeSymbol = semanticModel.GetTypeSymbol(type, context.CancellationToken);

                            string name = NameGenerator.Default.CreateUniqueLocalName(
                                typeSymbol,
                                semanticModel,
                                declarator.SpanStart,
                                cancellationToken: context.CancellationToken);

                            if (name != null)
                            {
                                context.RegisterRefactoring(
                                    $"Add identifier '{name}'",
                                    c => RefactorAsync(context.Document, type, name, c));
                            }
                        }
                    }
                }
            }
        }
예제 #7
0
        private static SyntaxTriviaList CleanTrivias(SyntaxTriviaList old, TextSpan span)
        {
            if (old.Span.Start > span.End || old.Span.End < span.Start)
            {
                return(old);
            }
            var before = old
                         .TakeWhile(x => x.Span.End < span.Start);
            var buffer = old
                         .SkipWhile(x => x.Span.Start < span.End)
                         .SkipWhile(x => x.IsKind(SyntaxKind.WhitespaceTrivia))
                         .ToList();
            var after = buffer.Any() && buffer.First().IsKind(SyntaxKind.EndOfLineTrivia) ? buffer.Skip(1) : buffer;
            var list  = SyntaxTriviaList.Empty
                        .AddRange(before)
                        .AddRange(after);

            return(list);
        }
        /// <summary>
        /// Determines if the node should be json serialized based on the precedence of
        /// a //json single line comment
        /// </summary>
        public static bool ShouldBeConvertedToJson(this SyntaxNode node, SyntaxTriviaList leadingTrivia)
        {
            if (leadingTrivia == default)
            {
                return(false);
            }

            var singleLineCommentIndex = leadingTrivia.IndexOf(SyntaxKind.SingleLineCommentTrivia);

            if (singleLineCommentIndex == -1)
            {
                return(false);
            }

            // all trivia after the single line should be whitespace or end of line
            if (!leadingTrivia
                .SkipWhile((l, i) => i < singleLineCommentIndex)
                .Any(l => l.IsKind(SyntaxKind.EndOfLineTrivia) || l.IsKind(SyntaxKind.WhitespaceTrivia)))
            {
                return(false);
            }

            return(SingleLineJsonComment.IsMatch(leadingTrivia.ElementAt(singleLineCommentIndex).ToFullString()));
        }
        private static async Task <StatementListInfo> RefactorAsync <TStatement>(
            Document document,
            TStatement statement,
            StatementListInfo statementsInfo,
            Func <TStatement, TStatement> createNewStatement,
            int count,
            bool removeReturnStatement,
            CancellationToken cancellationToken) where TStatement : StatementSyntax
        {
            int statementIndex = statementsInfo.IndexOf(statement);

            var returnStatement = (ReturnStatementSyntax)statementsInfo[statementIndex + 1];

            ExpressionSyntax returnExpression    = returnStatement.Expression;
            ExpressionSyntax newReturnExpression = null;
            SyntaxTriviaList newTrailingTrivia   = default;

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

            ISymbol symbol = semanticModel.GetSymbol(returnExpression, cancellationToken);

            if (symbol.Kind == SymbolKind.Local &&
                statementIndex > 0 &&
                statementsInfo[statementIndex - 1] is LocalDeclarationStatementSyntax localDeclarationStatement &&
                !localDeclarationStatement.ContainsDiagnostics &&
                !localDeclarationStatement.SpanOrTrailingTriviaContainsDirectives() &&
                !statement.GetLeadingTrivia().Any(f => f.IsDirective))
            {
                SeparatedSyntaxList <VariableDeclaratorSyntax> declarators = localDeclarationStatement.Declaration.Variables;

                VariableDeclaratorSyntax declarator = declarators.FirstOrDefault(f => semanticModel.GetDeclaredSymbol(f, cancellationToken)?.Equals(symbol) == true);

                if (declarator != null)
                {
                    ExpressionSyntax value = declarator.Initializer?.Value;

                    if (removeReturnStatement || value != null)
                    {
                        IEnumerable <ReferencedSymbol> referencedSymbols = await SymbolFinder.FindReferencesAsync(symbol, document.Solution(), cancellationToken).ConfigureAwait(false);

                        if (referencedSymbols.First().Locations.Count() == count + 1)
                        {
                            newReturnExpression = value;

                            if (declarators.Count == 1)
                            {
                                if (!removeReturnStatement &&
                                    returnStatement.GetTrailingTrivia().IsEmptyOrWhitespace())
                                {
                                    SyntaxTriviaList trailingTrivia = localDeclarationStatement.GetTrailingTrivia();

                                    if (trailingTrivia
                                        .SkipWhile(f => f.IsWhitespaceTrivia())
                                        .FirstOrDefault()
                                        .IsKind(SyntaxKind.SingleLineCommentTrivia))
                                    {
                                        newTrailingTrivia = trailingTrivia;
                                    }
                                }

                                SyntaxRemoveOptions removeOptions = SyntaxRefactorings.GetRemoveOptions(localDeclarationStatement);

                                if (newTrailingTrivia.Any())
                                {
                                    removeOptions &= ~SyntaxRemoveOptions.KeepTrailingTrivia;
                                }

                                statementsInfo = statementsInfo.RemoveNode(localDeclarationStatement, removeOptions);
                                statementIndex--;
                            }
                            else
                            {
                                statementsInfo = statementsInfo.ReplaceNode(localDeclarationStatement, localDeclarationStatement.RemoveNode(declarator, SyntaxRefactorings.GetRemoveOptions(declarator)));
                            }

                            returnStatement = (ReturnStatementSyntax)statementsInfo[statementIndex + 1];
                        }
                    }
                }
            }

            if (removeReturnStatement)
            {
                statementsInfo = statementsInfo.RemoveNode(returnStatement, SyntaxRefactorings.GetRemoveOptions(returnStatement));
            }
            else if (newReturnExpression != null)
            {
                ReturnStatementSyntax newReturnStatement = returnStatement.WithExpression(newReturnExpression.WithTriviaFrom(returnExpression));

                if (newTrailingTrivia.Any())
                {
                    newReturnStatement = newReturnStatement.WithTrailingTrivia(newTrailingTrivia);
                }

                statementsInfo = statementsInfo.ReplaceNode(returnStatement, newReturnStatement);
            }

            StatementSyntax oldNode = statementsInfo[statementIndex];

            TStatement newNode = createNewStatement((TStatement)oldNode).WithFormatterAnnotation();

            return(statementsInfo.ReplaceNode(oldNode, newNode));
        }
예제 #10
0
 public static IEnumerable <SyntaxTrivia> SkipInitialWhitespace(this SyntaxTriviaList triviaList)
 => triviaList.SkipWhile(t => t.Kind() == SyntaxKind.WhitespaceTrivia);
 public static IEnumerable <SyntaxTrivia> SkipInitialWhitespace(this SyntaxTriviaList triviaList)
 {
     return(triviaList.SkipWhile(t => t.CSharpKind() == SyntaxKind.WhitespaceTrivia));
 }