private static decimal ProcessObjectInitializer(ObjectCreationExpressionSyntax target, decimal lastTemporaryIndex, ref SyntaxNode newRoot, ref SyntaxNode[] originalObjectExpressionSyntax, ref IEnumerable<KeyValuePair<SyntaxNode, SyntaxNode>> replacedNodes, int depth = 0) { depth++; var objectCreation = target; if (objectCreation.Initializer.IsKind(SyntaxKind.ObjectInitializerExpression)) { var initializerInfo = GetModel(target).GetTypeInfo(target); var tempName = initializerInfo.Type.Name + "_helper_" + lastTemporaryIndex++; var assignments = new List<SyntaxNode>(); foreach (var expression in objectCreation.Initializer.Expressions) { var localExpression = (expression as AssignmentExpressionSyntax); if (localExpression == null) continue; var right = localExpression.Right; var targets = expression.DescendantNodes() .OfType<ObjectCreationExpressionSyntax>() .Where(k => k.Ancestors().OfType<ObjectCreationExpressionSyntax>().First() == target); var objectCreationExpressionSyntaxs = targets as ObjectCreationExpressionSyntax[] ?? targets.ToArray(); var noriginalObjectExpressionSyntax = objectCreationExpressionSyntaxs.ToArray<SyntaxNode>().ToArray(); foreach (var ntarget in noriginalObjectExpressionSyntax) { lastTemporaryIndex = ProcessObjectInitializer((ObjectCreationExpressionSyntax)ntarget, lastTemporaryIndex, ref newRoot, ref originalObjectExpressionSyntax, ref replacedNodes, depth); } if (noriginalObjectExpressionSyntax.Any()) { bool contained; try { newRoot.GetCurrentNode(right); contained = true; } catch (Exception) { contained = false; } if (contained) { if (right is MemberAccessExpressionSyntax) // Since Roslyn 1.0.0, old method doesnt work ... { var mar = right as MemberAccessExpressionSyntax; contained = !(mar.Expression.ToString() == replacedNodes.Last().Key.ToString()); } else if (right is ObjectCreationExpressionSyntax) { var mar = right as ObjectCreationExpressionSyntax; contained = !mar.Initializer.DescendantNodes().OfType<ObjectCreationExpressionSyntax>().Any(); //!(mar.ToString () == replacedNodes.Last ().Key.ToString ()); } } if (!contained || replacedNodes.Count() == 1) // We been replaced { try { var str = replacedNodes.Last().Value.ToFullString(); if (right is MemberAccessExpressionSyntax) { var mar = right as MemberAccessExpressionSyntax; right = SyntaxFactory.ParseExpression(str + "." + mar.Name.ToFullString()); } else { // for // replacedNodes.Any(k => k.Key == right); right = SyntaxFactory.ParseExpression(str); // (ExpressionSyntax)replacedNodes.FirstOrDefault(o => o.Key.ToFullString() == right.ToFullString()).Value; } replacedNodes = replacedNodes.Except(replacedNodes.Last()); } catch (Exception) { // throw; } } } var newAssignment = SyntaxFactory.ExpressionStatement( SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.MemberAccessExpression( SyntaxKind.SimpleMemberAccessExpression, SyntaxFactory.IdentifierName( tempName), SyntaxFactory.IdentifierName( localExpression.Left.As<IdentifierNameSyntax>() .ToFullString())), right) ).NormalizeWhitespace(); assignments.Add(newAssignment); // var varName = declarator.Identifier.Text + "_helper_"+ e + lastTemporaryIndex++; } var statements = new List<StatementSyntax>(); ObjectCreationExpressionSyntax newObjectCreation; if (objectCreation.ArgumentList == null || (!objectCreation.ArgumentList.Arguments.Any())) { var text = objectCreation.WithInitializer(null).ToFullString().Trim(); if (!text.EndsWith("()")) text += "()"; var exp = SyntaxFactory.ParseExpression(text); newObjectCreation = (ObjectCreationExpressionSyntax)exp; //SyntaxFactory.ObjectCreationExpression(objectCreation.Type); } else { newObjectCreation = objectCreation.WithInitializer(null).WithArgumentList(objectCreation.ArgumentList); } var local = SyntaxFactory.LocalDeclarationStatement( SyntaxFactory.VariableDeclaration( target.Type, SyntaxFactory.SeparatedList(new[] { SyntaxFactory.VariableDeclarator( SyntaxFactory.Identifier(tempName), null, SyntaxFactory.EqualsValueClause(newObjectCreation)) }) ) ).NormalizeWhitespace(); statements.Add(local); statements.AddRange(assignments.Cast<StatementSyntax>()); var listS = SyntaxFactory.List(statements); var newList2 = new List<ObjectCreationExpressionSyntax>(); var union2 = originalObjectExpressionSyntax.Union(new SyntaxNode[] { target }); foreach (var statementSyntax in union2) { try { newList2.Add((ObjectCreationExpressionSyntax)newRoot.GetCurrentNode(statementSyntax)); } catch (Exception ex) { } } if (!newList2.Contains(target)) { // originalObjectExpressionSyntax = originalObjectExpressionSyntax.Union(new SyntaxNode[] { target }).ToArray(); } originalObjectExpressionSyntax = originalObjectExpressionSyntax.Where(l => l != null).ToArray(); newRoot = newRoot.TrackNodes(originalObjectExpressionSyntax); try { var currentNode = newRoot.GetCurrentNode(target); var lastStatement = currentNode.Ancestors().OfType<StatementSyntax>().First(); newRoot = newRoot.InsertNodesBefore(lastStatement, listS); // var currentNodes = newRoot.GetCurrentNodes<SyntaxNode>(originalObjectExpressionSyntax); newRoot = newRoot.TrackNodes(originalObjectExpressionSyntax); currentNode = newRoot.GetCurrentNode(target); var newName = SyntaxFactory.ParseExpression(tempName); var nDict = new Dictionary<SyntaxNode, SyntaxNode>(); foreach (var replacedNode in replacedNodes) nDict[replacedNode.Key] = replacedNode.Value; nDict[currentNode] = newName; replacedNodes = nDict; // newRoot = newRoot; newRoot = newRoot.ReplaceNode(currentNode, newName); var newList = new List<ObjectCreationExpressionSyntax>(); var union = originalObjectExpressionSyntax.Union(nDict.Values); //.Union(new SyntaxNode[]{newName}); foreach (var statementSyntax in union) { try { // if(statementSyntax==newName) // { // newList.Add((ObjectCreationExpressionSyntax) (newName)); // continue; // } var syntaxNode = newRoot.GetCurrentNode(statementSyntax); newList.Add((ObjectCreationExpressionSyntax)syntaxNode); } catch (Exception ex) { } } originalObjectExpressionSyntax = newList.ToArray(); newRoot = newRoot.TrackNodes(originalObjectExpressionSyntax); } catch (Exception ex) { } } return lastTemporaryIndex; }