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 async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken);

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

            if (initializer == null)
            {
                return;
            }

            if (initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                initializer.Parent?.IsKind(SyntaxKind.CollectionInitializerExpression) == true)
            {
                initializer = (InitializerExpressionSyntax)initializer.Parent;
            }

            if (initializer.Expressions.Count > 0 &&
                !initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                initializer.Parent?.IsAnyKind(
                    SyntaxKind.ArrayCreationExpression,
                    SyntaxKind.ImplicitArrayCreationExpression,
                    SyntaxKind.ObjectCreationExpression,
                    SyntaxKind.CollectionInitializerExpression) == true)
            {
                if (initializer.IsSingleline(includeExteriorTrivia: false))
                {
                    context.RegisterRefactoring(
                        "Format initializer on multiple lines",
                        cancellationToken => FormatInitializerOnMultipleLinesAsync(
                            context.Document,
                            initializer,
                            cancellationToken));
                }
                else if (initializer.Expressions.All(expression => expression.IsSingleline()))
                {
                    context.RegisterRefactoring(
                        "Format initializer on a single line",
                        cancellationToken => FormatInitializerOnSingleLineAsync(
                            context.Document,
                            initializer,
                            cancellationToken));
                }
            }

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

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

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.FormatInitializer) &&
                    expressions.Any() &&
                    !initializer.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                    initializer.Parent?.IsKind(
                        SyntaxKind.ArrayCreationExpression,
                        SyntaxKind.ImplicitArrayCreationExpression,
                        SyntaxKind.ObjectCreationExpression,
                        SyntaxKind.CollectionInitializerExpression) == true)
                {
                    if (initializer.IsSingleLine(includeExteriorTrivia: false))
                    {
                        context.RegisterRefactoring(
                            "Format initializer on multiple lines",
                            cancellationToken => FormatInitializerOnMultipleLinesRefactoring.RefactorAsync(
                                context.Document,
                                initializer,
                                cancellationToken));
                    }
                    else if (expressions.All(expression => expression.IsSingleLine()))
                    {
                        context.RegisterRefactoring(
                            "Format initializer on a single line",
                            cancellationToken => FormatInitializerOnSingleLineRefactoring.RefactorAsync(
                                context.Document,
                                initializer,
                                cancellationToken));
                    }
                }

                if (context.IsRefactoringEnabled(RefactoringIdentifiers.ExpandInitializer))
                {
                    await ExpandInitializerRefactoring.ComputeRefactoringsAsync(context, initializer).ConfigureAwait(false);
                }
            }
        }
예제 #4
0
        public static InitializerExpressionSyntax ToMultiLine(InitializerExpressionSyntax initializer, CancellationToken cancellationToken)
        {
            SyntaxNode parent = initializer.Parent;

            if (parent.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !initializer.IsKind(SyntaxKind.CollectionInitializerExpression))
            {
                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(NewLine())))));
            }
            else
            {
                SyntaxTrivia trivia = initializer.GetIndentation(cancellationToken);

                SyntaxTriviaList braceTrivia      = TriviaList(NewLine(), trivia);
                SyntaxTriviaList expressionTrivia = TriviaList(NewLine(), trivia, SingleIndentation(trivia));

                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(expressionTrivia))))
                       .WithOpenBraceToken(initializer.OpenBraceToken.WithLeadingTrivia(braceTrivia))
                       .WithCloseBraceToken(initializer.CloseBraceToken.WithLeadingTrivia(braceTrivia)));
            }
        }
예제 #5
0
        public static InitializerExpressionSyntax ToMultiLine(InitializerExpressionSyntax initializer, CancellationToken cancellationToken)
        {
            SyntaxNode parent = initializer.Parent;

            if (parent.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !initializer.IsKind(SyntaxKind.CollectionInitializerExpression))
            {
                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(NewLine())))));
            }
            else
            {
                string indent = GetLineIndent(initializer, cancellationToken);

                SyntaxTriviaList braceTrivia      = ParseLeadingTrivia(Environment.NewLine + indent);
                SyntaxTriviaList expressionTrivia = ParseLeadingTrivia(Environment.NewLine + IncreaseIndent(indent));

                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(expressionTrivia))))
                       .WithOpenBraceToken(initializer.OpenBraceToken.WithLeadingTrivia(braceTrivia))
                       .WithCloseBraceToken(initializer.CloseBraceToken.WithLeadingTrivia(braceTrivia)));
            }
        }
예제 #6
0
        public static InitializerExpressionSyntax ToMultiLine(InitializerExpressionSyntax initializer, CancellationToken cancellationToken)
        {
            SyntaxNode parent = initializer.Parent;

            SyntaxTrivia endOfLine = DetermineEndOfLine(initializer);

            if (parent.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !initializer.IsKind(SyntaxKind.CollectionInitializerExpression))
            {
                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(endOfLine)))));
            }
            else
            {
                IndentationAnalysis indentationAnalysis = AnalyzeIndentation(initializer, cancellationToken);

                SyntaxTriviaList braceTrivia      = TriviaList(endOfLine, indentationAnalysis.Indentation);
                SyntaxTriviaList expressionTrivia = TriviaList(endOfLine, indentationAnalysis.GetIncreasedIndentationTrivia());

                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(expressionTrivia))))
                       .WithOpenBraceToken(initializer.OpenBraceToken.WithLeadingTrivia(braceTrivia))
                       .WithCloseBraceToken(initializer.CloseBraceToken.WithLeadingTrivia(braceTrivia)));
            }
        }
        private static InitializerExpressionSyntax GetMultilineInitializer(InitializerExpressionSyntax initializer)
        {
            SyntaxNode parent = initializer.Parent;

            if (parent.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !initializer.IsKind(SyntaxKind.CollectionInitializerExpression))
            {
                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(CSharpFactory.NewLineTrivia()))))
                       .WithFormatterAnnotation());
            }

            SyntaxTriviaList indent  = SyntaxUtility.GetIndentTrivia(initializer);
            SyntaxTriviaList indent2 = indent.Add(CSharpFactory.IndentTrivia());

            indent  = indent.Insert(0, CSharpFactory.NewLineTrivia());
            indent2 = indent2.Insert(0, CSharpFactory.NewLineTrivia());

            return(initializer
                   .WithExpressions(
                       SeparatedList(
                           initializer.Expressions.Select(expression => expression.WithLeadingTrivia(indent2))))
                   .WithOpenBraceToken(initializer.OpenBraceToken.WithLeadingTrivia(indent))
                   .WithCloseBraceToken(initializer.CloseBraceToken.WithLeadingTrivia(indent))
                   .WithFormatterAnnotation());
        }
예제 #8
0
        private static InitializerExpressionSyntax GetMultilineInitializer(InitializerExpressionSyntax initializer)
        {
            SyntaxNode parent = initializer.Parent;

            if (parent.IsKind(SyntaxKind.ObjectCreationExpression) &&
                !initializer.IsKind(SyntaxKind.CollectionInitializerExpression))
            {
                return(initializer
                       .WithExpressions(
                           SeparatedList(
                               initializer.Expressions.Select(expression => expression.WithLeadingTrivia(SyntaxHelper.NewLine))))
                       .WithAdditionalAnnotations(Formatter.Annotation));
            }

            SyntaxTriviaList indent  = initializer.GetIndentTrivia();
            SyntaxTriviaList indent2 = indent.Add(SyntaxHelper.DefaultIndent);

            indent  = indent.Insert(0, SyntaxHelper.NewLine);
            indent2 = indent2.Insert(0, SyntaxHelper.NewLine);

            return(initializer
                   .WithExpressions(
                       SeparatedList(
                           initializer.Expressions.Select(expression => expression.WithLeadingTrivia(indent2))))
                   .WithOpenBraceToken(initializer.OpenBraceToken.WithLeadingTrivia(indent))
                   .WithCloseBraceToken(initializer.CloseBraceToken.WithLeadingTrivia(indent))
                   .WithAdditionalAnnotations(Formatter.Annotation));
        }
        public override SyntaxNode VisitInitializerExpression(InitializerExpressionSyntax node)
        {
            TypeSyntax typeToCast = null;
            var        rankCount  = 0;

            if (node.Parent is ArrayCreationExpressionSyntax array)
            {
                typeToCast = array.Type.ElementType;
                rankCount  = array.Type.RankSpecifiers.Count - 1;
            }
            else if (node.IsKind(SyntaxKind.CollectionInitializerExpression) && node.Parent is ObjectCreationExpressionSyntax obj) // e.g. List<int> { document.Field }
            {
                var name = obj.Type as GenericNameSyntax;
                if (name == null && obj.Type is QualifiedNameSyntax qualifiedName)
                {
                    name = qualifiedName.Right as GenericNameSyntax;
                }

                if (name != null)
                {
                    var arguments = name.TypeArgumentList.Arguments;
                    if (arguments.Count == 1)
                    {
                        typeToCast = arguments[0];
                    }
                }
            }

            if (typeToCast != null)
            {
                var castedExpression = new SeparatedSyntaxList <ExpressionSyntax>();
                foreach (var expression in node.Expressions)
                {
                    if (expression is InitializerExpressionSyntax initializerExpression) // e.g. List<int> { document.Field }
                    {
                        var expressions = initializerExpression.Expressions;
                        if (expressions.Count == 1)
                        {
                            var innerExpression = expressions[0];

                            expressions           = expressions.Replace(innerExpression, CastExpression(typeToCast, rankCount, innerExpression));
                            initializerExpression = initializerExpression.WithExpressions(expressions);
                        }

                        castedExpression = castedExpression.Add(initializerExpression);
                        continue;
                    }

                    castedExpression = castedExpression.Add(CastExpression(typeToCast, rankCount, expression));
                }

                return(node.WithExpressions(castedExpression));
            }

            return(node);
        }
예제 #10
0
 public override void VisitInitializerExpression(InitializerExpressionSyntax node)
 {
     if (node.IsKind(SyntaxKind.CollectionInitializerExpression))
     {
         foreach (var addExpression in node.Expressions)
         {
             VisitSymbol(context.SemanticModel.GetCollectionInitializerSymbolInfo(addExpression).Symbol);
         }
     }
     base.VisitInitializerExpression(node);
 }
예제 #11
0
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer)
        {
            if (initializer.IsKind(SyntaxKind.ObjectInitializerExpression, SyntaxKind.CollectionInitializerExpression) &&
                initializer.Expressions.Any() &&
                initializer.Parent?.IsKind(SyntaxKind.ObjectCreationExpression) == true &&
                await CanExpandAsync(context, initializer).ConfigureAwait(false))
            {
                switch (initializer.Parent.Parent?.Kind())
                {
                case SyntaxKind.SimpleAssignmentExpression:
                {
                    var assignmentExpression = (AssignmentExpressionSyntax)initializer.Parent.Parent;

                    if (assignmentExpression.Left != null &&
                        assignmentExpression.Parent?.IsKind(SyntaxKind.ExpressionStatement) == true &&
                        assignmentExpression.Parent.Parent?.IsKind(SyntaxKind.Block) == true)
                    {
                        context.RegisterRefactoring(
                            Title,
                            cancellationToken => RefactorAsync(
                                context.Document,
                                initializer,
                                (ExpressionStatementSyntax)assignmentExpression.Parent,
                                assignmentExpression.Left.WithoutTrivia(),
                                cancellationToken));
                    }

                    break;
                }

                case SyntaxKind.EqualsValueClause:
                {
                    var equalsValueClause = (EqualsValueClauseSyntax)initializer.Parent.Parent;

                    if (equalsValueClause.Parent?.IsKind(SyntaxKind.VariableDeclarator) == true &&
                        equalsValueClause.Parent.Parent?.IsKind(SyntaxKind.VariableDeclaration) == true &&
                        equalsValueClause.Parent.Parent.Parent?.IsKind(SyntaxKind.LocalDeclarationStatement) == true &&
                        equalsValueClause.Parent.Parent.Parent.Parent?.IsKind(SyntaxKind.Block) == true)
                    {
                        context.RegisterRefactoring(
                            Title,
                            cancellationToken => RefactorAsync(
                                context.Document,
                                initializer,
                                (LocalDeclarationStatementSyntax)equalsValueClause.Parent.Parent.Parent,
                                IdentifierName(((VariableDeclaratorSyntax)equalsValueClause.Parent).Identifier.ToString()),
                                cancellationToken));
                    }

                    break;
                }
                }
            }
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer)
        {
            if (!initializer.IsKind(
                    SyntaxKind.ObjectInitializerExpression,
                    SyntaxKind.CollectionInitializerExpression))
            {
                return;
            }

            if (!initializer.Expressions.Any())
            {
                return;
            }

            SyntaxNode parent = initializer.Parent;

            if (parent?.Kind() != SyntaxKind.ObjectCreationExpression)
            {
                return;
            }

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

            if (!CanExpand(initializer, semanticModel, context.CancellationToken))
            {
                return;
            }

            if (parent.IsParentKind(SyntaxKind.SimpleAssignmentExpression))
            {
                SimpleAssignmentStatementInfo simpleAssignment = SyntaxInfo.SimpleAssignmentStatementInfo((AssignmentExpressionSyntax)parent.Parent);

                if (simpleAssignment.Success)
                {
                    RegisterRefactoring(context, simpleAssignment.Statement, initializer, simpleAssignment.Left);
                }
            }
            else
            {
                LocalDeclarationStatementInfo localInfo = SyntaxInfo.LocalDeclarationStatementInfo((ExpressionSyntax)parent);

                if (localInfo.Success)
                {
                    var declarator = (VariableDeclaratorSyntax)parent.Parent.Parent;

                    RegisterRefactoring(
                        context,
                        localInfo.Statement,
                        initializer,
                        IdentifierName(declarator.Identifier.ValueText));
                }
            }
        }
예제 #13
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));
        }
예제 #14
0
        public override SyntaxNode VisitInitializerExpression(InitializerExpressionSyntax node)
        {
            if (NormalizeWhitespaceOnly &&
                node.IsKind(SyntaxKind.ArrayInitializerExpression) &&
                _checkingMethod != RegisterInstanceName)
            {
                var openBrace = node.OpenBraceToken.WithLeadingTrivia(SyntaxHelper.Whitespace(12));
                node = node.WithOpenBraceToken(openBrace);
                var closeBrace = node.CloseBraceToken.WithLeadingTrivia(SyntaxHelper.EndOfLineTrivia, SyntaxHelper.Whitespace(12));
                node = node.WithCloseBraceToken(closeBrace);
            }

            return(base.VisitInitializerExpression(node !));
        }
        public override LuaSyntaxNode VisitInitializerExpression(InitializerExpressionSyntax node)
        {
            Contract.Assert(node.IsKind(SyntaxKind.ArrayInitializerExpression));
            var symbol = (IArrayTypeSymbol)semanticModel_.GetTypeInfo(node).ConvertedType;

            if (node.Expressions.Count > 0)
            {
                LuaExpressionSyntax           arrayType  = GetTypeName(symbol);
                LuaInvocationExpressionSyntax invocation = new LuaInvocationExpressionSyntax(arrayType);
                foreach (var expression in node.Expressions)
                {
                    var element = (LuaExpressionSyntax)expression.Accept(this);
                    invocation.AddArgument(element);
                }
                return(invocation);
            }
            else
            {
                LuaExpressionSyntax baseType = GetTypeName(symbol.ElementType);
                return(BuildEmptyArray(baseType));
            }
        }
        private IEnumerable <Instruction> ProcessInitializerExpression(InitializerExpressionSyntax initializerExpression)
        {
            if (!initializerExpression.IsKind(SyntaxKind.ArrayInitializerExpression))
            {
                return(NoInstructions);
            }

            var instructions = new List <Instruction>();

            // The target of this initialization should be the parent
            var parent = initializerExpression.Parent;

            // When parent is EqualsValueClause or InitializerExpression we need to go up one more level. See examples:
            // var x = { 1, 2 }
            // var y = new object[,] { { 1, 2 }, { 3, 4 } }
            if (parent is EqualsValueClauseSyntax ||
                parent is InitializerExpressionSyntax)
            {
                parent = parent.Parent;
            }

            var destination = GetOrProcessExpression(parent, instructions);

            foreach (var expression in initializerExpression.Expressions)
            {
                // When the initializer item is another initializer we already processed it so we should skip it now.
                // var y = new object[,] { { 1, 2 }, { 3, 4 } }
                if (!(expression is InitializerExpressionSyntax))
                {
                    var associatedExpression = GetOrProcessExpression(expression, instructions);
                    instructions.AddRange(BuildArraySetCall(initializerExpression, destination, associatedExpression));
                }
            }

            return(instructions);
        }
예제 #17
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);
                }
            }
        }
            private IEnumerable<ITypeSymbol> InferTypeInInitializerExpression(
                InitializerExpressionSyntax initializerExpression,
                ExpressionSyntax expressionOpt = null,
                SyntaxToken? previousToken = null)
            {
                if (initializerExpression.IsKind(SyntaxKind.ComplexElementInitializerExpression))
                {
                    // new Dictionary<K,V> { { x, ... } }
                    // new C { Prop = { { x, ... } } }
                    var parameterIndex = previousToken.HasValue
                            ? initializerExpression.Expressions.GetSeparators().ToList().IndexOf(previousToken.Value) + 1
                            : initializerExpression.Expressions.IndexOf(expressionOpt);

                    var addMethodSymbols = SemanticModel.GetCollectionInitializerSymbolInfo(initializerExpression).GetAllSymbols();
                    var addMethodParameterTypes = addMethodSymbols
                        .Cast<IMethodSymbol>()
                        .Where(a => a.Parameters.Length == initializerExpression.Expressions.Count)
                        .Select(a => a.Parameters.ElementAtOrDefault(parameterIndex)?.Type)
                        .WhereNotNull();

                    if (addMethodParameterTypes.Any())
                    {
                        return addMethodParameterTypes;
                    }
                }
                else if (initializerExpression.IsKind(SyntaxKind.CollectionInitializerExpression))
                {
                    if (expressionOpt != null)
                    {
                        // new List<T> { x, ... }
                        // new C { Prop = { x, ... } }
                        var addMethodSymbols = SemanticModel.GetCollectionInitializerSymbolInfo(expressionOpt).GetAllSymbols();
                        var addMethodParameterTypes = addMethodSymbols
                            .Cast<IMethodSymbol>()
                            .Where(a => a.Parameters.Length == 1)
                            .Select(a => a.Parameters[0].Type).WhereNotNull();
                        if (addMethodParameterTypes.Any())
                        {
                            return addMethodParameterTypes;
                        }
                    }
                    else
                    {
                        // new List<T> { x,
                        // new C { Prop = { x,

                        foreach (var sibling in initializerExpression.Expressions.Where(e => e.Kind() != SyntaxKind.ComplexElementInitializerExpression))
                        {
                            var types = GetTypes(sibling);
                            if (types.Any())
                            {
                                return types;
                            }
                        }
                    }
                }

                if (initializerExpression.IsParentKind(SyntaxKind.ImplicitArrayCreationExpression))
                {
                    // new[] { 1, x }

                    // First, try to infer the type that the array should be.  If we can infer an
                    // appropriate array type, then use the element type of the array.  Otherwise,
                    // look at the siblings of this expression and use their type instead.

                    var arrayTypes = this.InferTypes((ExpressionSyntax)initializerExpression.Parent);
                    var elementTypes = arrayTypes.OfType<IArrayTypeSymbol>().Select(a => a.ElementType).Where(IsUsableTypeFunc);

                    if (elementTypes.Any())
                    {
                        return elementTypes;
                    }

                    foreach (var sibling in initializerExpression.Expressions)
                    {
                        if (sibling != expressionOpt)
                        {
                            var types = GetTypes(sibling);
                            if (types.Any())
                            {
                                return types;
                            }
                        }
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.EqualsValueClause))
                {
                    // = { Foo() }
                    var equalsValueClause = (EqualsValueClauseSyntax)initializerExpression.Parent;
                    IEnumerable<ITypeSymbol> types = InferTypeInEqualsValueClause(equalsValueClause);

                    if (types.Any(t => t is IArrayTypeSymbol))
                    {
                        return types.OfType<IArrayTypeSymbol>().Select(t => t.ElementType);
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.ArrayCreationExpression))
                {
                    // new int[] { Foo() } 
                    var arrayCreation = (ArrayCreationExpressionSyntax)initializerExpression.Parent;
                    IEnumerable<ITypeSymbol> types = GetTypes(arrayCreation);

                    if (types.Any(t => t is IArrayTypeSymbol))
                    {
                        return types.OfType<IArrayTypeSymbol>().Select(t => t.ElementType);
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.ObjectCreationExpression))
                {
                    // new List<T> { Foo() } 

                    var objectCreation = (ObjectCreationExpressionSyntax)initializerExpression.Parent;

                    IEnumerable<ITypeSymbol> types = GetTypes(objectCreation);
                    if (types.Any(t => t is INamedTypeSymbol))
                    {
                        return types.OfType<INamedTypeSymbol>().SelectMany(t =>
                            GetCollectionElementType(t, parameterIndex: 0));
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.SimpleAssignmentExpression))
                {
                    // new Foo { a = { Foo() } }

                    if (expressionOpt != null)
                    {
                        var addMethodSymbols = SemanticModel.GetCollectionInitializerSymbolInfo(expressionOpt).GetAllSymbols();
                        var addMethodParameterTypes = addMethodSymbols.Select(a => ((IMethodSymbol)a).Parameters[0].Type).WhereNotNull();
                        if (addMethodParameterTypes.Any())
                        {
                            return addMethodParameterTypes;
                        }
                    }

                    var assignExpression = (AssignmentExpressionSyntax)initializerExpression.Parent;
                    IEnumerable<ITypeSymbol> types = GetTypes(assignExpression.Left);

                    if (types.Any(t => t is INamedTypeSymbol))
                    {
                        // new Foo { a = { Foo() } }
                        var parameterIndex = previousToken.HasValue
                                ? initializerExpression.Expressions.GetSeparators().ToList().IndexOf(previousToken.Value) + 1
                                : initializerExpression.Expressions.IndexOf(expressionOpt);

                        return types.OfType<INamedTypeSymbol>().SelectMany(t =>
                            GetCollectionElementType(t, 0));
                    }
                }

                return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
            }
            private IEnumerable<ITypeSymbol> InferTypeInInitializerExpression(
                InitializerExpressionSyntax initializerExpression,
                ExpressionSyntax expressionOpt = null,
                SyntaxToken? previousToken = null)
            {
                if (initializerExpression.IsParentKind(SyntaxKind.ImplicitArrayCreationExpression))
                {
                    // First, try to infer the type that the array should be.  If we can infer an
                    // appropriate array type, then use the element type of the array.  Otherwise,
                    // look at the siblings of this expression and use their type instead.

                    var arrayTypes = this.InferTypes((ExpressionSyntax)initializerExpression.Parent);
                    var elementTypes = arrayTypes.OfType<IArrayTypeSymbol>().Select(a => a.ElementType).Where(e => !IsUnusableType(e));

                    if (elementTypes.Any())
                    {
                        return elementTypes;
                    }

                    // { foo(), |
                    if (previousToken.HasValue && previousToken.Value.Kind() == SyntaxKind.CommaToken)
                    {
                        var sibling = initializerExpression.Expressions.FirstOrDefault(e => e.SpanStart < previousToken.Value.SpanStart);
                        if (sibling != null)
                        {
                            var types = GetTypes(sibling);
                            if (types.Any())
                            {
                                return types;
                            }
                        }
                    }

                    foreach (var sibling in initializerExpression.Expressions)
                    {
                        if (sibling != expressionOpt)
                        {
                            var types = GetTypes(sibling);
                            if (types.Any())
                            {
                                return types;
                            }
                        }
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.EqualsValueClause))
                {
                    // = { Foo() }
                    var equalsValueClause = (EqualsValueClauseSyntax)initializerExpression.Parent;
                    IEnumerable<ITypeSymbol> types = InferTypeInEqualsValueClause(equalsValueClause);

                    if (types.Any(t => t is IArrayTypeSymbol))
                    {
                        return types.OfType<IArrayTypeSymbol>().Select(t => t.ElementType);
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.ArrayCreationExpression))
                {
                    // new int[] { Foo() } 
                    var symbols = _semanticModel.GetCollectionInitializerSymbolInfo(initializerExpression).GetAllSymbols();

                    if (symbols.Any(t => t is INamedTypeSymbol))
                    {
                        return symbols.OfType<INamedTypeSymbol>();
                    }

                    var arrayCreation = (ArrayCreationExpressionSyntax)initializerExpression.Parent;
                    IEnumerable<ITypeSymbol> types = GetTypes(arrayCreation);

                    if (types.Any(t => t is IArrayTypeSymbol))
                    {
                        return types.OfType<IArrayTypeSymbol>().Select(t => t.ElementType);
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.ObjectCreationExpression))
                {
                    // new List<T> { Foo() } 

                    var objectCreation = (ObjectCreationExpressionSyntax)initializerExpression.Parent;

                    IEnumerable<ITypeSymbol> types = GetTypes(objectCreation);
                    if (types.Any(t => t is INamedTypeSymbol))
                    {
                        return types.OfType<INamedTypeSymbol>().SelectMany(t =>
                            GetCollectionElementType(t, parameterIndex: 0));
                    }
                }
                else if ((initializerExpression.IsParentKind(SyntaxKind.ComplexElementInitializerExpression) &&
                          initializerExpression.Parent.IsParentKind(SyntaxKind.ObjectCreationExpression)) ||
                         (initializerExpression.IsKind(SyntaxKind.ComplexElementInitializerExpression) &&
                          initializerExpression.IsParentKind(SyntaxKind.CollectionInitializerExpression) &&
                          initializerExpression.Parent.IsParentKind(SyntaxKind.ObjectCreationExpression)))
                {
                    // new Dictionary<K,V> { { Foo(), ... } }
                    var objectCreation = (ObjectCreationExpressionSyntax)initializerExpression.Parent.Parent;
                    var symbols = _semanticModel.GetCollectionInitializerSymbolInfo(initializerExpression).GetAllSymbols();

                    if (symbols.Any(t => t is INamedTypeSymbol))
                    {
                        return symbols.OfType<INamedTypeSymbol>();
                    }

                    IEnumerable<ITypeSymbol> types = GetTypes(objectCreation);

                    if (types.Any(t => t is INamedTypeSymbol))
                    {
                        var parameterIndex = previousToken.HasValue
                            ? initializerExpression.Expressions.GetWithSeparators().IndexOf(previousToken.Value) + 1
                            : initializerExpression.Expressions.IndexOf(expressionOpt);

                        return types.OfType<INamedTypeSymbol>().SelectMany(t =>
                            GetCollectionElementType(t,
                                parameterIndex: parameterIndex));
                    }
                }
                else if (initializerExpression.IsParentKind(SyntaxKind.SimpleAssignmentExpression))
                {
                    // new Foo { a = { Foo() } }
                    var symbols = _semanticModel.GetCollectionInitializerSymbolInfo(initializerExpression).GetAllSymbols();

                    if (symbols.Any(t => t is INamedTypeSymbol))
                    {
                        return symbols.OfType<INamedTypeSymbol>();
                    }

                    var assignExpression = (AssignmentExpressionSyntax)initializerExpression.Parent;
                    IEnumerable<ITypeSymbol> types = GetTypes(assignExpression.Left);

                    if (types.Any(t => t is INamedTypeSymbol))
                    {
                        var parameterIndex = previousToken.HasValue
                            ? initializerExpression.Expressions.GetWithSeparators().IndexOf(previousToken.Value) + 1
                            : initializerExpression.Expressions.IndexOf(expressionOpt);

                        return types.OfType<INamedTypeSymbol>().SelectMany(t =>
                            GetCollectionElementType(t,
                                parameterIndex: parameterIndex));
                    }
                }

                return SpecializedCollections.EmptyEnumerable<ITypeSymbol>();
            }
        public static void ComputeRefactorings(
            RefactoringContext context,
            InitializerExpressionSyntax initializer,
            SemanticModel semanticModel)
        {
            Debug.Assert(initializer.IsKind(SyntaxKind.ObjectInitializerExpression, SyntaxKind.WithInitializerExpression), initializer.Kind().ToString());

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

            if (typeSymbol?.IsErrorType() != false)
            {
                return;
            }

            if (typeSymbol.IsAnonymousType)
            {
                return;
            }

            int position = initializer.OpenBraceToken.Span.End;

            ImmutableArray <ISymbol> symbols = semanticModel.LookupSymbols(position, typeSymbol);

            if (!symbols.Any())
            {
                return;
            }

            SeparatedSyntaxList <ExpressionSyntax> expressions = initializer.Expressions;

            if (expressions.Any())
            {
                var initializedPropertyNames = new HashSet <string>();

                foreach (ExpressionSyntax expression in expressions)
                {
                    Debug.Assert(expression.IsKind(SyntaxKind.SimpleAssignmentExpression), expression.Kind().ToString());

                    if (expression.IsKind(SyntaxKind.SimpleAssignmentExpression))
                    {
                        SimpleAssignmentExpressionInfo assignmentInfo = SyntaxInfo.SimpleAssignmentExpressionInfo((AssignmentExpressionSyntax)expression);

                        if (assignmentInfo.Success)
                        {
                            ExpressionSyntax left = assignmentInfo.Left;

                            Debug.Assert(left.IsKind(SyntaxKind.IdentifierName), left.Kind().ToString());

                            if (left is IdentifierNameSyntax identifierName)
                            {
                                initializedPropertyNames.Add(identifierName.Identifier.ValueText);
                            }
                        }
                    }
                }

                Dictionary <string, IPropertySymbol> namesToProperties = null;

                foreach (ISymbol symbol in symbols)
                {
                    if (initializedPropertyNames.Contains(symbol.Name))
                    {
                        continue;
                    }

                    IPropertySymbol propertySymbol = GetInitializableProperty(symbol, position, semanticModel);

                    if (propertySymbol == null)
                    {
                        continue;
                    }

                    if (namesToProperties != null)
                    {
                        if (namesToProperties.ContainsKey(propertySymbol.Name))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        namesToProperties = new Dictionary <string, IPropertySymbol>();
                    }

                    namesToProperties.Add(propertySymbol.Name, propertySymbol);
                }

                if (namesToProperties != null)
                {
                    Document document = context.Document;

                    context.RegisterRefactoring(
                        "Initialize all properties",
                        ct =>
                    {
                        IEnumerable <IPropertySymbol> propertySymbols = namesToProperties.Select(f => f.Value);
                        return(RefactorAsync(document, initializer, propertySymbols, initializeToDefault: false, ct));
                    },
                        RefactoringDescriptors.AddAllPropertiesToInitializer);
                }
            }
            else if (HasAccessiblePropertySetter())
            {
                Document document = context.Document;

                context.RegisterRefactoring(
                    "Initialize all properties",
                    ct =>
                {
                    IEnumerable <IPropertySymbol> propertySymbols = GetInitializableProperties(initializer, symbols, semanticModel);
                    return(RefactorAsync(document, initializer, propertySymbols, initializeToDefault: false, ct));
                },
                    RefactoringDescriptors.AddAllPropertiesToInitializer);
            }

            bool HasAccessiblePropertySetter()
            {
                foreach (ISymbol symbol in symbols)
                {
                    if (GetInitializableProperty(symbol, position, semanticModel) != null)
                    {
                        return(true);
                    }
                }

                return(false);
            }
        }
        public static async Task ComputeRefactoringsAsync(RefactoringContext context, InitializerExpressionSyntax initializer)
        {
            if (initializer.IsKind(
                    SyntaxKind.ObjectInitializerExpression,
                    SyntaxKind.CollectionInitializerExpression) &&
                initializer.Expressions.Any())
            {
                SyntaxNode parent = initializer.Parent;

                if (parent?.IsKind(SyntaxKind.ObjectCreationExpression) == true)
                {
                    SemanticModel semanticModel = await context.GetSemanticModelAsync().ConfigureAwait(false);

                    if (CanExpand(initializer, semanticModel, context.CancellationToken))
                    {
                        parent = parent.Parent;

                        switch (parent?.Kind())
                        {
                        case SyntaxKind.SimpleAssignmentExpression:
                        {
                            var assignmentExpression = (AssignmentExpressionSyntax)parent;

                            ExpressionSyntax left = assignmentExpression.Left;

                            if (left != null)
                            {
                                parent = assignmentExpression.Parent;

                                if (parent?.IsKind(SyntaxKind.ExpressionStatement) == true)
                                {
                                    RegisterRefactoring(context, (StatementSyntax)parent, initializer, left);
                                }
                            }

                            break;
                        }

                        case SyntaxKind.EqualsValueClause:
                        {
                            var equalsValueClause = (EqualsValueClauseSyntax)parent;

                            parent = equalsValueClause.Parent;

                            if (parent?.IsKind(SyntaxKind.VariableDeclarator) == true)
                            {
                                parent = parent.Parent;

                                if (parent?.IsKind(SyntaxKind.VariableDeclaration) == true)
                                {
                                    parent = parent.Parent;

                                    if (parent?.IsKind(SyntaxKind.LocalDeclarationStatement) == true)
                                    {
                                        var variableDeclarator = (VariableDeclaratorSyntax)equalsValueClause.Parent;

                                        RegisterRefactoring(
                                            context,
                                            (StatementSyntax)parent,
                                            initializer,
                                            IdentifierName(variableDeclarator.Identifier.ValueText));
                                    }
                                }
                            }

                            break;
                        }
                        }
                    }
                }
            }
        }
예제 #22
0
        public override void VisitInitializerExpression(InitializerExpressionSyntax node)
        {
            var oper = m_Model.GetOperation(node);

            if (null != oper)
            {
                bool isCollection        = node.IsKind(SyntaxKind.CollectionInitializerExpression);
                bool isObjectInitializer = node.IsKind(SyntaxKind.ObjectInitializerExpression);
                bool isArray             = node.IsKind(SyntaxKind.ArrayInitializerExpression);
                bool isComplex           = node.IsKind(SyntaxKind.ComplexElementInitializerExpression);
                if (isCollection)
                {
                    if (null != oper.Type)
                    {
                        bool isDictionary = IsImplementationOfSys(oper.Type, "IDictionary");
                        bool isList       = IsImplementationOfSys(oper.Type, "IList");
                        if (isDictionary)
                        {
                            CodeBuilder.Append("{");
                            var args = node.Expressions;
                            int ct   = args.Count;
                            for (int i = 0; i < ct; ++i)
                            {
                                var exp = args[i] as InitializerExpressionSyntax;
                                if (null != exp)
                                {
                                    CodeBuilder.Append("[tostring(");
                                    VisitToplevelExpression(exp.Expressions[0], string.Empty);
                                    CodeBuilder.Append(")] = ");
                                    VisitToplevelExpression(exp.Expressions[1], string.Empty);
                                }
                                else
                                {
                                    Log(args[i], "Dictionary init error !");
                                }
                                if (i < ct - 1)
                                {
                                    CodeBuilder.Append(", ");
                                }
                            }
                            CodeBuilder.Append("}");
                        }
                        else if (isList)
                        {
                            CodeBuilder.Append("{");
                            var args = node.Expressions;
                            int ct   = args.Count;
                            for (int i = 0; i < ct; ++i)
                            {
                                VisitExpressionSyntax(args[i]);
                                if (i < ct - 1)
                                {
                                    CodeBuilder.Append(", ");
                                }
                            }
                            CodeBuilder.Append("}");
                        }
                        else
                        {
                            CodeBuilder.Append("{");
                            var args = node.Expressions;
                            int ct   = args.Count;
                            for (int i = 0; i < ct; ++i)
                            {
                                VisitExpressionSyntax(args[i]);
                                if (i < ct - 1)
                                {
                                    CodeBuilder.Append(", ");
                                }
                            }
                            CodeBuilder.Append("}");
                        }
                    }
                    else
                    {
                        Log(node, "Can't find operation type ! operation info: {0}", oper.ToString());
                    }
                }
                else if (isComplex)
                {
                    CodeBuilder.Append("{");
                    var args = node.Expressions;
                    int ct   = args.Count;
                    for (int i = 0; i < ct; ++i)
                    {
                        VisitExpressionSyntax(args[i]);
                        if (i < ct - 1)
                        {
                            CodeBuilder.Append(", ");
                        }
                    }
                    CodeBuilder.Append("}");
                }
                else
                {
                    if (isArray)
                    {
                        CodeBuilder.Append("wraparray{");
                    }
                    var args = node.Expressions;
                    int ct   = args.Count;
                    for (int i = 0; i < ct; ++i)
                    {
                        var exp = args[i];
                        VisitToplevelExpression(exp, string.Empty);
                        if (i < ct - 1)
                        {
                            CodeBuilder.Append(", ");
                        }
                    }
                    if (isArray)
                    {
                        CodeBuilder.Append("}");
                    }
                }
            }
            else
            {
                Log(node, "Can't find operation info !");
            }
        }