public static bool CanRefactor(AccessorDeclarationSyntax accessorDeclaration, TextSpan?span = null)
        {
            BlockSyntax body = accessorDeclaration.Body;

            return(body != null &&
                   (span?.IsEmptyAndContainedInSpanOrBetweenSpans(accessorDeclaration) != false ||
                    span.Value.IsEmptyAndContainedInSpanOrBetweenSpans(body)) &&
                   !accessorDeclaration.AttributeLists.Any() &&
                   BlockExpressionAnalysis.SupportsExpressionBody(body, allowExpressionStatement: !accessorDeclaration.IsKind(SyntaxKind.GetAccessorDeclaration)) &&
                   (accessorDeclaration.Parent as AccessorListSyntax)?
                   .Accessors
                   .SingleOrDefault(shouldThrow: false)?
                   .Kind() != SyntaxKind.GetAccessorDeclaration);
        }
        private static SyntaxToken CreateSemicolonToken(BlockSyntax block, BlockExpressionAnalysis analysis)
        {
            SyntaxTriviaList trivia = analysis.SemicolonToken.TrailingTrivia;

            SyntaxTriviaList leading = block.CloseBraceToken.LeadingTrivia;

            if (!leading.IsEmptyOrWhitespace())
            {
                trivia = trivia.AddRange(leading);
            }

            SyntaxTriviaList trailing = block.CloseBraceToken.TrailingTrivia;

            if (!trailing.IsEmptyOrWhitespace() ||
                !analysis.SemicolonToken.TrailingTrivia.LastOrDefault().IsEndOfLineTrivia())
            {
                trivia = trivia.AddRange(trailing);
            }

            return(analysis.SemicolonToken.WithTrailingTrivia(trivia));
        }
        private static ArrowExpressionClauseSyntax CreateExpressionBody(BlockExpressionAnalysis analysis, SyntaxNode declaration)
        {
            SyntaxToken arrowToken = Token(SyntaxKind.EqualsGreaterThanToken);

            ExpressionSyntax expression = analysis.Expression;

            SyntaxToken keyword = analysis.ReturnOrThrowKeyword;

            switch (keyword.Kind())
            {
            case SyntaxKind.ThrowKeyword:
            {
                expression = ThrowExpression(keyword, expression);
                break;
            }

            case SyntaxKind.ReturnKeyword:
            {
                SyntaxTriviaList leading = keyword.LeadingTrivia;

                if (!leading.IsEmptyOrWhitespace())
                {
                    arrowToken = arrowToken.WithLeadingTrivia(leading);
                }

                SyntaxTriviaList trailing = keyword.TrailingTrivia;

                if (!trailing.IsEmptyOrWhitespace())
                {
                    arrowToken = arrowToken.WithTrailingTrivia(trailing);
                }

                break;
            }
            }

            expression = SyntaxTriviaAnalysis.SetIndentation(expression, declaration);

            return(ArrowExpressionClause(arrowToken, expression));
        }
        public static bool CanRefactor(PropertyDeclarationSyntax propertyDeclaration, TextSpan?span = null)
        {
            AccessorListSyntax accessorList = propertyDeclaration.AccessorList;

            if (accessorList != null &&
                span?.IsEmptyAndContainedInSpanOrBetweenSpans(accessorList) != false)
            {
                AccessorDeclarationSyntax accessor = propertyDeclaration
                                                     .AccessorList?
                                                     .Accessors
                                                     .SingleOrDefault(shouldThrow: false);

                if (accessor?.AttributeLists.Any() == false &&
                    accessor.IsKind(SyntaxKind.GetAccessorDeclaration) &&
                    accessor.Body != null &&
                    BlockExpressionAnalysis.SupportsExpressionBody(accessor.Body, allowExpressionStatement: false))
                {
                    return(true);
                }
            }

            return(false);
        }
 public static bool CanRefactor(ConversionOperatorDeclarationSyntax operatorDeclaration, TextSpan?span = null)
 {
     return(operatorDeclaration.Body != null &&
            span?.IsEmptyAndContainedInSpanOrBetweenSpans(operatorDeclaration.Body) != false &&
            BlockExpressionAnalysis.SupportsExpressionBody(operatorDeclaration.Body, allowExpressionStatement: false));
 }
 public static bool CanRefactor(MethodDeclarationSyntax methodDeclaration, TextSpan?span = null)
 {
     return(methodDeclaration.Body != null &&
            span?.IsEmptyAndContainedInSpanOrBetweenSpans(methodDeclaration.Body) != false &&
            BlockExpressionAnalysis.SupportsExpressionBody(methodDeclaration.Body));
 }
        private static SyntaxNode Refactor(SyntaxNode node)
        {
            switch (node.Kind())
            {
            case SyntaxKind.MethodDeclaration:
                {
                    var methodDeclaration            = (MethodDeclarationSyntax)node;
                    BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(methodDeclaration.Body);

                    return(methodDeclaration
                           .WithExpressionBody(CreateExpressionBody(analysis, methodDeclaration))
                           .WithSemicolonToken(CreateSemicolonToken(methodDeclaration.Body, analysis))
                           .WithBody(null));
                }

            case SyntaxKind.ConstructorDeclaration:
                {
                    var constructorDeclaration       = (ConstructorDeclarationSyntax)node;
                    BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(constructorDeclaration.Body);

                    return(constructorDeclaration
                           .WithExpressionBody(CreateExpressionBody(analysis, constructorDeclaration))
                           .WithSemicolonToken(CreateSemicolonToken(constructorDeclaration.Body, analysis))
                           .WithBody(null));
                }

            case SyntaxKind.DestructorDeclaration:
                {
                    var destructorDeclaration        = (DestructorDeclarationSyntax)node;
                    BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(destructorDeclaration.Body);

                    return(destructorDeclaration
                           .WithExpressionBody(CreateExpressionBody(analysis, destructorDeclaration))
                           .WithSemicolonToken(CreateSemicolonToken(destructorDeclaration.Body, analysis))
                           .WithBody(null));
                }

            case SyntaxKind.LocalFunctionStatement:
                {
                    var localFunction = (LocalFunctionStatementSyntax)node;
                    BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(localFunction.Body);

                    return(localFunction
                           .WithExpressionBody(CreateExpressionBody(analysis, localFunction))
                           .WithSemicolonToken(CreateSemicolonToken(localFunction.Body, analysis))
                           .WithBody(null));
                }

            case SyntaxKind.OperatorDeclaration:
            {
                var operatorDeclaration          = (OperatorDeclarationSyntax)node;
                BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(operatorDeclaration.Body);

                return(operatorDeclaration
                       .WithExpressionBody(CreateExpressionBody(analysis, operatorDeclaration))
                       .WithSemicolonToken(CreateSemicolonToken(operatorDeclaration.Body, analysis))
                       .WithBody(null));
            }

            case SyntaxKind.ConversionOperatorDeclaration:
            {
                var operatorDeclaration          = (ConversionOperatorDeclarationSyntax)node;
                BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(operatorDeclaration.Body);

                return(operatorDeclaration
                       .WithExpressionBody(CreateExpressionBody(analysis, operatorDeclaration))
                       .WithSemicolonToken(CreateSemicolonToken(operatorDeclaration.Body, analysis))
                       .WithBody(null));
            }

            case SyntaxKind.PropertyDeclaration:
            {
                var propertyDeclaration          = (PropertyDeclarationSyntax)node;
                BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(propertyDeclaration.AccessorList);

                return(propertyDeclaration
                       .WithExpressionBody(CreateExpressionBody(analysis, propertyDeclaration))
                       .WithSemicolonToken(CreateSemicolonToken(analysis.Block, analysis))
                       .WithAccessorList(null));
            }

            case SyntaxKind.IndexerDeclaration:
            {
                var indexerDeclaration           = (IndexerDeclarationSyntax)node;
                BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(indexerDeclaration.AccessorList);

                return(indexerDeclaration
                       .WithExpressionBody(CreateExpressionBody(analysis, indexerDeclaration))
                       .WithSemicolonToken(CreateSemicolonToken(analysis.Block, analysis))
                       .WithAccessorList(null));
            }

            case SyntaxKind.GetAccessorDeclaration:
            case SyntaxKind.SetAccessorDeclaration:
            case SyntaxKind.InitAccessorDeclaration:
            case SyntaxKind.AddAccessorDeclaration:
            case SyntaxKind.RemoveAccessorDeclaration:
            {
                var accessor = (AccessorDeclarationSyntax)node;
                BlockExpressionAnalysis analysis = BlockExpressionAnalysis.Create(accessor);

                return(accessor
                       .WithExpressionBody(CreateExpressionBody(analysis, accessor))
                       .WithSemicolonToken(CreateSemicolonToken(analysis.Block, analysis))
                       .WithBody(null));
            }

            default:
            {
                SyntaxDebug.Fail(node);
                return(node);
            }
            }
        }
 public static bool CanRefactor(LocalFunctionStatementSyntax localFunctionStatement, TextSpan?span = null)
 {
     return(localFunctionStatement.Body != null &&
            span?.IsEmptyAndContainedInSpanOrBetweenSpans(localFunctionStatement.Body) != false &&
            BlockExpressionAnalysis.SupportsExpressionBody(localFunctionStatement.Body));
 }