public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer)
        {
            if (initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                initializer.IsParentKind(SyntaxKind.CollectionInitializerExpression))
            {
                initializer = (InitializerExpressionSyntax)initializer.Parent;
            }

            if (context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(initializer) ||
                context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(initializer.Expressions))
            {
                SeparatedSyntaxList <ExpressionSyntax> expressions = initializer.Expressions;

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.FormatInitializer) &&
                    expressions.Any() &&
                    !initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                    initializer.IsParentKind(
                        SyntaxKind.ArrayCreationExpression,
                        SyntaxKind.ImplicitArrayCreationExpression,
                        SyntaxKind.ObjectCreationExpression,
                        SyntaxKind.CollectionInitializerExpression))
                {
                    if (initializer.IsSingleLine(includeExteriorTrivia: false))
                    {
                        context.RegisterRefactoring(
                            "Format initializer on multiple lines",
                            cancellationToken => SyntaxFormatter.ToMultiLineAsync(
                                context.Document,
                                initializer,
                                cancellationToken),
                            RefactoringIdentifiers.FormatInitializer);
                    }
                    else if (expressions.All(expression => expression.IsSingleLine()) &&
                             initializer.DescendantTrivia(initializer.Span).All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                    {
                        context.RegisterRefactoring(
                            "Format initializer on a single line",
                            cancellationToken => SyntaxFormatter.ToSingleLineAsync(
                                context.Document,
                                initializer,
                                cancellationToken),
                            RefactoringIdentifiers.FormatInitializer);
                    }
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandInitializer))
                {
                    await ExpandInitializerRefactoring.ComputeRefactoringsAsync(context, initializer).ConfigureAwait(false);
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.UseCSharp6DictionaryInitializer) &&
                    context.SupportsCSharp6)
                {
                    await UseCSharp6DictionaryInitializerRefactoring.ComputeRefactoringAsync(context, initializer).ConfigureAwait(false);
                }
            }
        }
예제 #2
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));
        }
예제 #3
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer)
        {
            if (initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                initializer.IsParentKind(SyntaxKind.CollectionInitializerExpression))
            {
                initializer = (InitializerExpressionSyntax)initializer.Parent;
            }

            if (context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(initializer) ||
                context.Span.IsEmptyAndContainedInSpanOrBetweenSpans(initializer.Expressions))
            {
                SeparatedSyntaxList <ExpressionSyntax> expressions = initializer.Expressions;

                if (context.IsRefactoringEnabled(RefactoringDescriptors.WrapInitializerExpressions) &&
                    expressions.Any() &&
                    !initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                    initializer.IsParentKind(
                        SyntaxKind.ArrayCreationExpression,
                        SyntaxKind.ImplicitArrayCreationExpression,
                        SyntaxKind.ObjectCreationExpression,
                        SyntaxKind.CollectionInitializerExpression,
                        SyntaxKind.WithExpression))
                {
                    if (initializer.IsSingleLine(includeExteriorTrivia: false))
                    {
                        context.RegisterRefactoring(
                            "Wrap initializer expression",
                            ct => SyntaxFormatter.ToMultiLineAsync(context.Document, initializer, ct),
                            RefactoringDescriptors.WrapInitializerExpressions);
                    }
                    else if (expressions.All(expression => expression.IsSingleLine()) &&
                             initializer.DescendantTrivia(initializer.Span).All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                    {
                        context.RegisterRefactoring(
                            "Unwrap initializer expressions",
                            ct => SyntaxFormatter.ToSingleLineAsync(
                                context.Document,
                                initializer.Parent,
                                TextSpan.FromBounds(initializer.OpenBraceToken.GetPreviousToken().Span.End, initializer.CloseBraceToken.Span.End),
                                ct),
                            RefactoringDescriptors.WrapInitializerExpressions);
                    }
                }

                if (context.IsRefactoringEnabled(RefactoringDescriptors.AddAllPropertiesToInitializer) &&
                    initializer.IsKind(SyntaxKind.ObjectInitializerExpression, SyntaxKind.WithInitializerExpression) &&
                    AddAllPropertiesToInitializerRefactoring.IsApplicableSpan(initializer, context.Span))
                {
                    SemanticModel semanticModdel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    AddAllPropertiesToInitializerRefactoring.ComputeRefactorings(context, initializer, semanticModdel);
                }

                await ExpandInitializerRefactoring.ComputeRefactoringsAsync(context, initializer).ConfigureAwait(false);

                if (context.IsRefactoringEnabled(RefactoringDescriptors.UseIndexInitializer) &&
                    context.SupportsCSharp6)
                {
                    await UseIndexInitializerRefactoring.ComputeRefactoringAsync(context, initializer).ConfigureAwait(false);
                }
            }
        }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Diagnostic diagnostic = context.Diagnostics[0];

            if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MoveInitializerExpressionsToConstructor))
            {
                return;
            }

            SyntaxNode root = await context.GetSyntaxRootAsync().ConfigureAwait(false);

            ObjectCreationExpressionSyntax objectCreationExpression = root
                                                                      .FindNode(context.Span, getInnermostNodeForTie: true)?
                                                                      .FirstAncestorOrSelf <ObjectCreationExpressionSyntax>();

            if (objectCreationExpression == null)
            {
                return;
            }

            switch (diagnostic.Id)
            {
            case CompilerDiagnosticIdentifiers.ThereIsNoArgumentGivenThatCorrespondsToRequiredFormalParameter:
            {
                if (!Settings.IsEnabled(diagnostic.Id, CodeFixIdentifiers.MoveInitializerExpressionsToConstructor))
                {
                    break;
                }

                if (!objectCreationExpression.Type.Span.Contains(diagnostic.Location.SourceSpan))
                {
                    return;
                }

                ArgumentListSyntax argumentList = objectCreationExpression.ArgumentList;

                if (argumentList?.Arguments.Any() == true)
                {
                    return;
                }

                InitializerExpressionSyntax initializer = objectCreationExpression.Initializer;

                if (initializer == null)
                {
                    return;
                }

                SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                List <ExpressionSyntax> expressions = null;

                foreach (ExpressionSyntax expression in initializer.Expressions)
                {
                    if (expression is AssignmentExpressionSyntax assignment &&
                        semanticModel.GetDiagnostic(
                            CompilerDiagnosticIdentifiers.PropertyOrIndexerCannotBeUsedInThisContextBecauseSetAccessorIsAccessible,
                            assignment.Left.Span,
                            context.CancellationToken) != null)
                    {
                        (expressions ??= new List <ExpressionSyntax>()).Add(expression);
                    }
                }

                if (expressions == null)
                {
                    return;
                }

                TypeSyntax type = objectCreationExpression.Type;

                if (argumentList == null)
                {
                    argumentList = ArgumentList().WithTrailingTrivia(type.GetTrailingTrivia());
                    type         = type.WithoutTrailingTrivia();
                }

                SeparatedSyntaxList <ArgumentSyntax> arguments = expressions
                                                                 .Select(f => Argument(((AssignmentExpressionSyntax)f).Right))
                                                                 .ToSeparatedSyntaxList();

                argumentList = argumentList.WithArguments(arguments);

                ObjectCreationExpressionSyntax newObjectCreationExpression = objectCreationExpression.Update(
                    objectCreationExpression.NewKeyword,
                    type,
                    argumentList,
                    initializer);

                SymbolInfo symbolInfo = semanticModel.GetSpeculativeSymbolInfo(
                    objectCreationExpression.SpanStart,
                    newObjectCreationExpression,
                    SpeculativeBindingOption.BindAsExpression);

                if (symbolInfo.Symbol is IMethodSymbol methodSymbol &&
                    methodSymbol.MethodKind == MethodKind.Constructor)
                {
                    CodeAction codeAction = CodeAction.Create(
                        "Move initializer expressions to constructor",
                        ct =>
                        {
                            InitializerExpressionSyntax newInitializer = initializer.RemoveNodes(expressions, SyntaxRefactorings.DefaultRemoveOptions);

                            if (newInitializer.Expressions.Count == 0 &&
                                newInitializer
                                .DescendantTrivia(TextSpan.FromBounds(newInitializer.OpenBraceToken.SpanStart, newInitializer.CloseBraceToken.SpanStart))
                                .All(f => f.IsWhitespaceOrEndOfLineTrivia()))
                            {
                                newInitializer = null;

                                ArgumentListSyntax newArgumentList = newObjectCreationExpression
                                                                     .ArgumentList
                                                                     .TrimTrailingTrivia()
                                                                     .AppendToTrailingTrivia(initializer.GetTrailingTrivia());

                                newObjectCreationExpression = newObjectCreationExpression
                                                              .WithArgumentList(newArgumentList);
                            }

                            newObjectCreationExpression = newObjectCreationExpression
                                                          .WithInitializer(newInitializer)
                                                          .WithFormatterAnnotation();

                            return(context.Document.ReplaceNodeAsync(objectCreationExpression, newObjectCreationExpression, ct));
                        },
                        GetEquivalenceKey(diagnostic));

                    context.RegisterCodeFix(codeAction, diagnostic);
                }

                break;
            }
            }
        }