Beispiel #1
0
        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;
        }