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); } } }
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); } } }
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))); } }
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))); } }
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()); }
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); }
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); }
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)); } } }
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)); }
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); }
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; } } } } } }
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 !"); } }