示例#1
0
 private string[] Rewrite()
 {
     var rewriter = new SharpSixRewriter(this);
     var result = new string[this.SourceFiles.Count];
     Task.WaitAll(this.SourceFiles.Select((file, index) => Task.Run(() => result[index] = new SharpSixRewriter(rewriter).Rewrite(index))).ToArray());
     return result;
 }
        private string[] Rewrite()
        {
            var rewriter = new SharpSixRewriter(this);
            var result   = new string[this.SourceFiles.Count];

            // Run in parallel only and only if logger level is not trace.
            if (this.Log.LoggerLevel == LoggerLevel.Trace)
            {
                this.Log.Trace("Rewriting/replacing code from files one after the other (not parallel) due to logger level being 'trace'.");
                this.SourceFiles.Select((file, index) => new { file, index }).ToList()
                .ForEach(entry => result[entry.index] = new SharpSixRewriter(rewriter).Rewrite(entry.index));
            }
            else
            {
                Task.WaitAll(this.SourceFiles.Select((file, index) => Task.Run(() => result[index] = new SharpSixRewriter(rewriter).Rewrite(index))).ToArray());
            }

            return(result);
        }
示例#3
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model, SharpSixRewriter rewriter)
        {
            var unit           = root as CompilationUnitSyntax;
            var removingUsings = new List <UsingDirectiveSyntax>();

            foreach (var u in unit.Usings)
            {
                try
                {
                    if (u.StaticKeyword.RawKind == (int)SyntaxKind.StaticKeyword)
                    {
                        removingUsings.Add(u);
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(u, e);
                }
            }

            return(root.RemoveNodes(removingUsings, SyntaxRemoveOptions.KeepDirectives));
        }
示例#4
0
        public static TypeSyntax GenerateTypeSyntax(ITypeSymbol type, SemanticModel model, int pos, SharpSixRewriter rewriter)
        {
            if (type.IsTupleType)
            {
                var elements = ((INamedTypeSymbol)type).TupleElements;
                var types    = new List <TypeSyntax>();
                foreach (var el in elements)
                {
                    types.Add(SyntaxHelper.GenerateTypeSyntax(el.Type, model, pos, rewriter));
                }

                return(SyntaxFactory.GenericName(SyntaxFactory.Identifier("System.ValueTuple"), SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList <TypeSyntax>(types))));
            }

            var typeName = type.FullyQualifiedName(false);

            if (rewriter.usingStaticNames.Any(n => typeName.StartsWith(n + '.')))
            {
                return(SyntaxFactory.ParseTypeName(type.ToDisplayString()));
            }
            else if (type is INamedTypeSymbol namedType && namedType.IsGenericType)
            {
                var elements = namedType.TypeArguments;
                var types    = new List <TypeSyntax>();
                foreach (var el in elements)
                {
                    types.Add(SyntaxHelper.GenerateTypeSyntax(el, model, pos, rewriter));
                }

                return(SyntaxFactory.GenericName(
                           SyntaxFactory.Identifier(
                               type.ToMinimalDisplayString(
                                   model,
                                   pos,
                                   new SymbolDisplayFormat(
                                       genericsOptions: SymbolDisplayGenericsOptions.None
                                       )
                                   )
                               ),
                           SyntaxFactory.TypeArgumentList(
                               SyntaxFactory.SeparatedList <TypeSyntax>(types)
                               )
                           ));
            }

            return(SyntaxFactory.ParseTypeName(type.ToMinimalDisplayString(model, pos)));
        }
示例#5
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model, SharpSixRewriter rewriter)
        {
            var assignments   = root.DescendantNodes().OfType <AssignmentExpressionSyntax>();
            var updatedBlocks = new Dictionary <BlockSyntax, List <StatementSyntax> >();
            var locals        = new List <LocalDeclarationStatementSyntax>();

            foreach (var assignment in assignments)
            {
                try
                {
                    var identifier = assignment.Left as IdentifierNameSyntax;
                    if (identifier != null)
                    {
                        var local = assignment.GetParent <LocalDeclarationStatementSyntax>();
                        if (local != null && locals.Contains(local))
                        {
                            continue;
                        }
                        locals.Add(local);

                        var name = identifier.Identifier.ValueText;

                        if (local != null && local.Declaration.Variables.Any(v => v.Identifier.ValueText == name))
                        {
                            var block = local.Ancestors().OfType <BlockSyntax>().First();

                            var statements = updatedBlocks.ContainsKey(block) ? updatedBlocks[block] : block.Statements.ToList();
                            var index      = statements.IndexOf(local);

                            foreach (var variable in local.Declaration.Variables)
                            {
                                var newLocal = SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(local.Declaration.Type.WithoutTrivia(), SyntaxFactory.SingletonSeparatedList(SyntaxFactory.VariableDeclarator(variable.Identifier.ValueText)))).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n"));

                                if (local.Declaration.Variables.First().Equals(variable))
                                {
                                    newLocal = newLocal.WithLeadingTrivia(local.GetLeadingTrivia());
                                }

                                statements.Insert(index++, newLocal);

                                if (variable.Initializer != null)
                                {
                                    var equals = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression, SyntaxFactory.IdentifierName(variable.Identifier.ValueText), variable.Initializer.Value.WithoutTrivia())).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n"));
                                    if (local.Declaration.Variables.Last().Equals(variable))
                                    {
                                        equals = equals.WithTrailingTrivia(local.GetTrailingTrivia());
                                    }

                                    statements.Insert(index++, equals);
                                }
                            }

                            statements.Remove(local);

                            updatedBlocks[block] = statements;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(assignment, e);
                }
            }

            if (updatedBlocks.Count > 0)
            {
                root = root.ReplaceNodes(updatedBlocks.Keys, (b1, b2) => b1.WithStatements(SyntaxFactory.List <StatementSyntax>(updatedBlocks[b1])));
            }

            return(root);
        }
示例#6
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model, Func <SyntaxNode, Tuple <SyntaxTree, SemanticModel> > updater, SharpSixRewriter rewriter)
        {
            var discards = root
                           .DescendantNodes()
                           .OfType <DiscardDesignationSyntax>();

            var outVars = root
                          .DescendantNodes()
                          .OfType <ArgumentSyntax>()
                          .Where(arg => arg.Expression is DeclarationExpressionSyntax && arg.RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword);

            var outDiscardVars = root
                                 .DescendantNodes()
                                 .OfType <ArgumentSyntax>()
                                 .Where(arg => {
                if (arg.Expression is IdentifierNameSyntax ins && ins.Identifier.ValueText == DISCARD_IDENTIFIER)
                {
                    var si = model.GetSymbolInfo(arg.Expression);
                    return(si.Symbol == null || si.Symbol.Kind == SymbolKind.Discard);
                }

                return(false);
            });

            var discardAssigments = root
                                    .DescendantNodes()
                                    .OfType <AssignmentExpressionSyntax>()
                                    .Where(assignment => {
                if (assignment.Left is IdentifierNameSyntax ins && ins.Identifier.ValueText == DISCARD_IDENTIFIER)
                {
                    var si = model.GetSymbolInfo(assignment.Left);
                    return(si.Symbol == null || si.Symbol.Kind == SymbolKind.Discard);
                }

                return(false);
            });

            var updatedMembers = new Dictionary <MemberAccessExpressionSyntax, string>();

            foreach (var memberAccess in root.DescendantNodes().OfType <MemberAccessExpressionSyntax>())
            {
                var symbol = model.GetSymbolInfo(memberAccess).Symbol;
                if (symbol != null && symbol is IFieldSymbol && symbol.ContainingType.IsTupleType)
                {
                    var field      = symbol as IFieldSymbol;
                    var tupleField = field.CorrespondingTupleField;
                    updatedMembers[memberAccess] = tupleField.Name;
                }
            }

            var updatedStatements  = new Dictionary <StatementSyntax, List <LocalDeclarationStatementSyntax> >();
            var updatedDiscards    = new Dictionary <DiscardDesignationSyntax, string>();
            var updatedDiscardVars = new Dictionary <ArgumentSyntax, string>();

            var tempIndex = 0;

            foreach (var discard in discards)
            {
                try
                {
                    var noLocal     = false;
                    var parentTuple = discard.GetParent <TupleExpressionSyntax>();
                    if (parentTuple != null && parentTuple.Parent is AssignmentExpressionSyntax ae && ae.Left == parentTuple)
                    {
                        noLocal = true;
                    }

                    var typeInfo        = model.GetTypeInfo(discard.Parent);
                    var beforeStatement = discard.Ancestors().OfType <StatementSyntax>().FirstOrDefault();

                    if (beforeStatement != null)
                    {
                        if (typeInfo.Type != null)
                        {
                            string instance = DISCARD_VARIABLE + ++tempIndex;
                            if (beforeStatement.Parent != null)
                            {
                                var info = LocalUsageGatherer.GatherInfo(model, beforeStatement.Parent);

                                while (info.DirectlyOrIndirectlyUsedLocals.Any(s => s.Name == instance) || info.Names.Contains(instance))
                                {
                                    instance = DISCARD_VARIABLE + ++tempIndex;
                                }
                            }

                            if (!noLocal)
                            {
                                var locals  = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();
                                var varDecl = SyntaxFactory.VariableDeclaration(SyntaxHelper.GenerateTypeSyntax(typeInfo.Type, model, discard.Parent.GetLocation().SourceSpan.Start, rewriter)).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                                                                                                                  SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(instance))
                                                                                                                                                                                                                  ));

                                var local = SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n"));
                                locals.Add(local);

                                updatedStatements[beforeStatement] = locals;
                            }

                            updatedDiscards[discard] = instance;
                        }
                        else if (discard.Parent is DeclarationPatternSyntax && !(discard.Parent.Parent is IsPatternExpressionSyntax))
                        {
                            string instance = DISCARD_VARIABLE + ++tempIndex;
                            if (beforeStatement.Parent != null)
                            {
                                var info = LocalUsageGatherer.GatherInfo(model, beforeStatement.Parent);

                                while (info.DirectlyOrIndirectlyUsedLocals.Any(s => s.Name == instance) || info.Names.Contains(instance))
                                {
                                    instance = DISCARD_VARIABLE + ++tempIndex;
                                }
                            }

                            updatedDiscards[discard] = instance;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(discard, e);
                }
            }

            foreach (var discardVar in outDiscardVars)
            {
                try
                {
                    var typeInfo = model.GetTypeInfo(discardVar.Expression);

                    if (typeInfo.Type != null)
                    {
                        var beforeStatement = discardVar.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                        if (beforeStatement != null)
                        {
                            string instance = DISCARD_VARIABLE + ++tempIndex;
                            if (beforeStatement.Parent != null)
                            {
                                var info = LocalUsageGatherer.GatherInfo(model, beforeStatement.Parent);

                                while (info.DirectlyOrIndirectlyUsedLocals.Any(s => s.Name == instance) || info.Names.Contains(instance))
                                {
                                    instance = DISCARD_VARIABLE + ++tempIndex;
                                }
                            }

                            var locals  = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();
                            var varDecl = SyntaxFactory.VariableDeclaration(SyntaxHelper.GenerateTypeSyntax(typeInfo.Type, model, discardVar.Expression.GetLocation().SourceSpan.Start, rewriter)).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                                                                                                                     SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(instance))
                                                                                                                                                                                                                     ));

                            var local = SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n"));
                            locals.Add(local);

                            updatedStatements[beforeStatement] = locals;
                            updatedDiscardVars[discardVar]     = instance;
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(discardVar, e);
                }
            }

            foreach (var outVar in outVars)
            {
                try
                {
                    if (((DeclarationExpressionSyntax)outVar.Expression).Designation.Kind() == SyntaxKind.DiscardDesignation)
                    {
                        continue;
                    }

                    var typeInfo = model.GetTypeInfo(outVar.Expression);

                    if (typeInfo.Type != null)
                    {
                        var beforeStatement = outVar.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                        if (beforeStatement != null)
                        {
                            if (outVar.Expression is DeclarationExpressionSyntax de)
                            {
                                var designation = de.Designation as SingleVariableDesignationSyntax;

                                if (designation != null)
                                {
                                    var locals  = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();
                                    var varDecl = SyntaxFactory.VariableDeclaration(SyntaxHelper.GenerateTypeSyntax(typeInfo.Type, model, outVar.Expression.GetLocation().SourceSpan.Start, rewriter)).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                                                                                                                         SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(designation.Identifier.ValueText))
                                                                                                                                                                                                                         ));

                                    locals.Add(SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n")));

                                    updatedStatements[beforeStatement] = locals;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(outVar, e);
                }
            }

            var annotatedStatemnts   = new Dictionary <SyntaxAnnotation, List <LocalDeclarationStatementSyntax> >();
            var annotatedDiscards    = new Dictionary <SyntaxAnnotation, string>();
            var annotatedDiscardVars = new Dictionary <SyntaxAnnotation, string>();
            var annotatedAssigments  = new List <SyntaxAnnotation>();
            var annotatedMembers     = new Dictionary <SyntaxAnnotation, string>();

            var keys = updatedStatements.Keys.Cast <SyntaxNode>()
                       .Concat(updatedDiscards.Keys.Cast <SyntaxNode>())
                       .Concat(updatedDiscardVars.Keys.Cast <SyntaxNode>())
                       .Concat(discardAssigments)
                       .Concat(updatedMembers.Keys.Cast <SyntaxNode>());

            root = root.ReplaceNodes(keys, (n1, n2) =>
            {
                var annotation = new SyntaxAnnotation();

                if (n1 is AssignmentExpressionSyntax)
                {
                    annotatedAssigments.Add(annotation);
                }
                else if (n1 is DiscardDesignationSyntax)
                {
                    annotatedDiscards[annotation] = updatedDiscards[(DiscardDesignationSyntax)n1];
                }
                else if (n1 is ArgumentSyntax)
                {
                    annotatedDiscardVars[annotation] = updatedDiscardVars[(ArgumentSyntax)n1];
                }
                else if (n1 is MemberAccessExpressionSyntax)
                {
                    annotatedMembers[annotation] = updatedMembers[(MemberAccessExpressionSyntax)n1];
                }
                else
                {
                    annotatedStatemnts[annotation] = updatedStatements[(StatementSyntax)n1];
                }

                n2 = n2.WithAdditionalAnnotations(annotation);
                return(n2);
            });

            foreach (var annotation in annotatedDiscards.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var name          = annotatedDiscards[annotation];

                root = root.ReplaceNode(annotatedNode, SyntaxFactory.SingleVariableDesignation(SyntaxFactory.Identifier(name)).NormalizeWhitespace());
            }

            foreach (var annotation in annotatedDiscardVars.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var name          = annotatedDiscardVars[annotation];

                root = root.ReplaceNode(annotatedNode, ((ArgumentSyntax)annotatedNode).WithExpression(SyntaxFactory.IdentifierName(name)));
            }

            foreach (var annotation in annotatedAssigments)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                root = root.ReplaceNode(annotatedNode, ((AssignmentExpressionSyntax)annotatedNode).WithLeft(SyntaxFactory.IdentifierName("Bridge.Script.Discard")));
            }

            outVars = root
                      .DescendantNodes()
                      .OfType <ArgumentSyntax>()
                      .Where(arg => arg.Expression is DeclarationExpressionSyntax && arg.RefOrOutKeyword.Kind() == SyntaxKind.OutKeyword);

            root = root.ReplaceNodes(outVars, (n1, n2) =>
            {
                var designation = ((DeclarationExpressionSyntax)n2.Expression).Designation as SingleVariableDesignationSyntax;

                if (designation == null)
                {
                    return(n2);
                }

                return(SyntaxFactory.Argument(SyntaxFactory.IdentifierName(designation.Identifier)).WithRefKindKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword)).WithRefOrOutKeyword(SyntaxFactory.Token(SyntaxKind.OutKeyword)).NormalizeWhitespace());
            });

            foreach (var annotation in annotatedStatemnts.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var varStatements = annotatedStatemnts[annotation];

                if (annotatedNode.Parent is BlockSyntax || !(annotatedNode is StatementSyntax))
                {
                    root = root.InsertNodesBefore(annotatedNode, varStatements);
                }
                else
                {
                    var list = new List <StatementSyntax>(varStatements);
                    list.Add((StatementSyntax)annotatedNode);
                    root = root.ReplaceNode(annotatedNode, SyntaxFactory.Block(list).NormalizeWhitespace());
                }
            }

            var discardPatterns = root.DescendantNodes().OfType <IsPatternExpressionSyntax>().Where(pattern => pattern.Pattern is DeclarationPatternSyntax dp && dp.Designation.Kind() == SyntaxKind.DiscardDesignation);

            if (discardPatterns.Any())
            {
                root = root.ReplaceNodes(discardPatterns, (n1, n2) => {
                    return(SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression, SyntaxFactory.Token(SyntaxKind.TrueKeyword)));
                });
            }

            foreach (var annotation in annotatedMembers.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var name          = annotatedMembers[annotation];

                root = root.ReplaceNode(annotatedNode, ((MemberAccessExpressionSyntax)annotatedNode).WithName(SyntaxFactory.IdentifierName(name)).NormalizeWhitespace());
            }

            return(root);
        }
示例#7
0
        private static void ConvertInitializers(SeparatedSyntaxList <ExpressionSyntax> initializers, string instance, List <StatementSyntax> statements, List <InitializerInfo> infos)
        {
            var idx = 0;

            foreach (var init in initializers)
            {
                var info  = infos[idx++];
                var mInfo = info != null && info.method != null ? info.method : null;
                if (mInfo != null)
                {
                    if (mInfo.IsStatic)
                    {
                        var ie = SyntaxHelper.GenerateStaticMethodCall(mInfo.Name,
                                                                       mInfo.ContainingType.FullyQualifiedName(),
                                                                       new[]
                        {
                            SyntaxFactory.Argument(SyntaxFactory.IdentifierName(instance)),
                            SyntaxFactory.Argument(init.WithoutTrivia())
                        }, mInfo.TypeArguments.ToArray());
                        statements.Add(ie);
                    }
                    else
                    {
                        ArgumentSyntax[] arguments = null;
                        if (init.Kind() == SyntaxKind.ComplexElementInitializerExpression)
                        {
                            var complexInit = (InitializerExpressionSyntax)init;

                            arguments = new ArgumentSyntax[complexInit.Expressions.Count];
                            for (int i = 0; i < complexInit.Expressions.Count; i++)
                            {
                                arguments[i] = SyntaxFactory.Argument(complexInit.Expressions[i].WithoutTrivia());
                            }
                        }
                        else
                        {
                            arguments = new[]
                            {
                                SyntaxFactory.Argument(init.WithoutTrivia())
                            };
                        }

                        var ie = SyntaxHelper.GenerateMethodCall(mInfo.Name, instance, arguments, mInfo.TypeArguments.ToArray());
                        statements.Add(ie);
                    }
                }
                else
                {
                    var be = (AssignmentExpressionSyntax)init;

                    if (be.Right is InitializerExpressionSyntax)
                    {
                        string name = null;
                        if (be.Left is IdentifierNameSyntax)
                        {
                            var identifier = (IdentifierNameSyntax)be.Left;
                            name = instance + "." + identifier.Identifier.ValueText;
                        }
                        else if (be.Left is ImplicitElementAccessSyntax)
                        {
                            name = SyntaxFactory.ElementAccessExpression(SyntaxFactory.IdentifierName(instance),
                                                                         ((ImplicitElementAccessSyntax)be.Left).ArgumentList.WithoutTrivia()).ToString();
                        }
                        else
                        {
                            name = instance;
                        }

                        SharpSixRewriter.ConvertInitializers(((InitializerExpressionSyntax)be.Right).Expressions, name, statements, info.nested);
                    }
                    else
                    {
                        var indexerKeys = be.Left as ImplicitElementAccessSyntax;

                        if (indexerKeys != null)
                        {
                            be = be.WithLeft(SyntaxFactory.ElementAccessExpression(SyntaxFactory.IdentifierName(instance),
                                                                                   indexerKeys.ArgumentList.WithoutTrivia()));
                        }
                        else
                        {
                            var identifier = (IdentifierNameSyntax)be.Left;
                            be =
                                be.WithLeft(SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression,
                                                                                 SyntaxFactory.IdentifierName(instance),
                                                                                 SyntaxFactory.IdentifierName(identifier.Identifier.ValueText)));
                        }

                        be = be.WithRight(be.Right.WithoutTrivia());
                        be = be.WithoutTrivia();

                        statements.Add(SyntaxFactory.ExpressionStatement(be, SyntaxFactory.Token(SyntaxKind.SemicolonToken)));
                    }
                }
            }
        }
示例#8
0
        public override SyntaxNode VisitObjectCreationExpression(ObjectCreationExpressionSyntax node)
        {
            bool needRewrite = false;
            List <InitializerInfo> initializerInfos = null;
            bool extensionMethodExists         = false;
            bool isImplicitElementAccessSyntax = false;

            if (node.Initializer != null)
            {
                initializerInfos = new List <InitializerInfo>();
                needRewrite      = NeedRewriteInitializer(node.Initializer, initializerInfos, ref extensionMethodExists, ref isImplicitElementAccessSyntax);
            }

            node = (ObjectCreationExpressionSyntax)base.VisitObjectCreationExpression(node);
            if (needRewrite)
            {
                if (this.IsExpressionOfT)
                {
                    if (isImplicitElementAccessSyntax)
                    {
                        var mapped = this.semanticModel.SyntaxTree.GetLineSpan(node.Span);
                        throw new Exception(string.Format(CultureInfo.InvariantCulture, "{2} - {3}({0},{1}): {4}", mapped.StartLinePosition.Line + 1, mapped.StartLinePosition.Character + 1, "Index collection initializer is not supported inside Expression<T>", this.semanticModel.SyntaxTree.FilePath, node.ToString()));
                    }

                    if (extensionMethodExists)
                    {
                        var mapped = this.semanticModel.SyntaxTree.GetLineSpan(node.Span);
                        throw new Exception(string.Format(CultureInfo.InvariantCulture, "{2} - {3}({0},{1}): {4}", mapped.StartLinePosition.Line + 1, mapped.StartLinePosition.Character + 1, "Extension method for collection initializer is not supported inside Expression<T>", this.semanticModel.SyntaxTree.FilePath, node.ToString()));
                    }

                    return(node);
                }

                var initializers        = node.Initializer.Expressions;
                ExpressionSyntax[] args = new ExpressionSyntax[2];
                var target = node.WithInitializer(null).WithoutTrivia();

                if (target.ArgumentList == null)
                {
                    target = target.WithArgumentList(SyntaxFactory.ArgumentList());
                }

                args[0] = target;

                List <StatementSyntax> statements = new List <StatementSyntax>();

                var parent = node.Parent;

                while (parent != null && !(parent is MethodDeclarationSyntax) && !(parent is ClassDeclarationSyntax))
                {
                    parent = parent.Parent;
                }

                string instance = "_o" + ++indexInstance;
                if (parent != null)
                {
                    var info = LocalUsageGatherer.GatherInfo(this.semanticModel, parent);
                    while (info.DirectlyOrIndirectlyUsedLocals.Any(s => s.Name == instance))
                    {
                        instance = "_o" + ++indexInstance;
                    }
                }

                SharpSixRewriter.ConvertInitializers(initializers, instance, statements, initializerInfos);

                statements.Add(SyntaxFactory.ReturnStatement(SyntaxFactory.IdentifierName(instance).WithLeadingTrivia(SyntaxFactory.Space)));

                var body   = SyntaxFactory.Block(statements);
                var lambda = SyntaxFactory.ParenthesizedLambdaExpression(SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Parameter(SyntaxFactory.Identifier(instance)) })), body);
                args[1] = lambda;

                var methodIdentifier = SyntaxFactory.IdentifierName("Bridge.Script.CallFor");
                var invocation       = SyntaxFactory.InvocationExpression(methodIdentifier, SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(args.Select(SyntaxFactory.Argument))));

                return(invocation);
            }

            return(node);
        }
示例#9
0
        public override SyntaxNode VisitArgument(ArgumentSyntax node)
        {
            var ti = this.semanticModel.GetTypeInfo(node.Expression);

            ITypeSymbol      type      = null;
            IMethodSymbol    method    = null;
            IParameterSymbol parameter = null;

            if (ti.Type != null && ti.Type.TypeKind == TypeKind.Delegate)
            {
                type = ti.Type;
            }
            else if (ti.ConvertedType != null && ti.ConvertedType.TypeKind == TypeKind.Delegate)
            {
                type = ti.ConvertedType;
            }

            if (type != null)
            {
                var list       = node.Parent as ArgumentListSyntax;
                var invocation = node.Parent.Parent as InvocationExpressionSyntax;

                if (list != null && invocation != null)
                {
                    method = this.semanticModel.GetSymbolInfo(invocation).Symbol as IMethodSymbol;

                    if (method != null)
                    {
                        if (node.NameColon != null)
                        {
                            if (node.NameColon.Name != null)
                            {
                                var nameText = node.NameColon.Name.Identifier.ValueText;
                                if (nameText != null)
                                {
                                    foreach (var p in method.Parameters)
                                    {
                                        if (string.Equals(p.Name, nameText, StringComparison.Ordinal))
                                        {
                                            parameter = p;
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            var index = list.Arguments.IndexOf(node);
                            if (index >= 0)
                            {
                                if (index < method.Parameters.Length)
                                {
                                    parameter = method.Parameters[index];
                                }
                                else if (index >= method.Parameters.Length && method.Parameters[method.Parameters.Length - 1].IsParams)
                                {
                                    parameter = method.Parameters[method.Parameters.Length - 1];
                                }
                            }
                        }
                    }
                }
            }
            var isParam = parameter != null && !SyntaxHelper.IsAnonymous(parameter.Type);
            var parent  = isParam && parameter.IsParams ? (InvocationExpressionSyntax)node.Parent.Parent : null;

            node = (ArgumentSyntax)base.VisitArgument(node);

            if (isParam)
            {
                var pType = parameter.Type;
                if (parameter.IsParams && SharpSixRewriter.IsExpandedForm(this.semanticModel, parent, method))
                {
                    pType = ((IArrayTypeSymbol)parameter.Type).ElementType;
                }

                if (node.Expression is CastExpressionSyntax && type.Equals(pType) || parameter.RefKind != RefKind.None)
                {
                    return(node);
                }

                if (pType.TypeKind == TypeKind.Delegate || parameter.IsParams && ((IArrayTypeSymbol)parameter.Type).ElementType.TypeKind == TypeKind.Delegate)
                {
                    var name = SyntaxFactory.IdentifierName(pType.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat)).WithoutTrivia();
                    var expr = node.Expression;

                    if (expr is LambdaExpressionSyntax || expr is AnonymousMethodExpressionSyntax)
                    {
                        expr = SyntaxFactory.ParenthesizedExpression(expr);
                    }

                    var cast = SyntaxFactory.CastExpression(name, expr);
                    node = node.WithExpression(cast);
                }
            }

            return(node);
        }
示例#10
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model, SharpSixRewriter rewriter)
        {
            var switches = root.DescendantNodes().OfType <SwitchStatementSyntax>().Where(sw => {
                return(sw.Sections.Any(s => s.Labels.Any(l => l is CasePatternSwitchLabelSyntax || l is CaseSwitchLabelSyntax csl && csl.Value is CastExpressionSyntax ce && ce.Expression.Kind() == SyntaxKind.DefaultLiteralExpression)));
            });

            var tempKey = 0;

            root = root.ReplaceNodes(switches, (s1, sw) =>
            {
                try
                {
                    var ifNodes = new List <IfStatementSyntax>();
                    BlockSyntax defaultBlock = null;
                    var isComplex            = IsExpressionComplexEnoughToGetATemporaryVariable.IsComplex(model, s1.Expression);
                    var switchExpression     = sw.Expression;
                    StatementSyntax switchConditionVariable = null;

                    var iType          = model.GetTypeInfo(s1.Expression).Type;
                    var expressionType = SyntaxFactory.ParseTypeName(iType.ToMinimalDisplayString(model, s1.Expression.GetLocation().SourceSpan.Start));

                    if (isComplex)
                    {
                        var key              = tempKey++;
                        var keyArg           = SyntaxFactory.LiteralExpression(SyntaxKind.StringLiteralExpression, SyntaxFactory.Literal("case_pattern" + key));
                        var methodIdentifier = SyntaxFactory.IdentifierName("global::Bridge.Script.ToTemp");

                        var toTemp = SyntaxFactory.InvocationExpression(methodIdentifier,
                                                                        SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg), SyntaxFactory.Argument(switchExpression) })));

                        switchConditionVariable = SyntaxFactory.ExpressionStatement(toTemp).NormalizeWhitespace();

                        var parentMethodIdentifier = SyntaxFactory.GenericName(SyntaxFactory.Identifier("global::Bridge.Script.FromTemp"),
                                                                               SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(new[] { expressionType })));
                        switchExpression = SyntaxFactory.InvocationExpression(parentMethodIdentifier,
                                                                              SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(new[] { SyntaxFactory.Argument(keyArg) })));
                    }

                    foreach (var section in sw.Sections)
                    {
                        // This should catch most (if not all) unhandled yet natively supported syntax usage
                        try
                        {
                            var tuple     = CollectCondition(switchExpression, section.Labels, expressionType);
                            var condition = tuple.Item1;
                            var variables = tuple.Item2;
                            var whens     = tuple.Item3;

                            var body     = SyntaxFactory.Block();
                            var whenBody = SyntaxFactory.Block();

                            foreach (var variable in variables)
                            {
                                body = body.WithStatements(body.Statements.Add(SyntaxFactory.LocalDeclarationStatement(variable)));
                            }

                            foreach (var statement in section.Statements)
                            {
                                if (whens.Count > 0)
                                {
                                    whenBody = whenBody.WithStatements(whenBody.Statements.Add(statement));
                                }
                                else
                                {
                                    body = body.WithStatements(body.Statements.Add(statement));
                                }
                            }

                            if (whens.Count > 0)
                            {
                                ExpressionSyntax whenCondition = whens[0];
                                for (int i = 1; i < whens.Count; ++i)
                                {
                                    whenCondition = SyntaxFactory.BinaryExpression(SyntaxKind.LogicalOrExpression, whenCondition, whens[i]);
                                }

                                body = body.WithStatements(body.Statements.Add(SyntaxFactory.IfStatement(whenCondition, whenBody)));
                            }

                            if (condition == null)
                            {
                                defaultBlock = body
                                               .WithLeadingTrivia(section.GetLeadingTrivia())
                                               .WithTrailingTrivia(section.GetTrailingTrivia());
                                break;
                            }

                            ifNodes.Add(SyntaxFactory.IfStatement(condition, body).WithLeadingTrivia(section.GetLeadingTrivia()));
                        }
                        catch (Exception e)
                        {
                            throw new ReplacerException(section, e);
                        }
                    }

                    var doBlock = SyntaxFactory.Block();
                    if (switchConditionVariable != null)
                    {
                        doBlock = doBlock.WithStatements(doBlock.Statements.Add(switchConditionVariable));
                    }

                    doBlock = doBlock.WithStatements(doBlock.Statements.AddRange(ifNodes));

                    if (defaultBlock != null)
                    {
                        doBlock = doBlock.WithStatements(doBlock.Statements.Add(defaultBlock));
                    }

                    var doStatement = SyntaxFactory.DoStatement(doBlock, SyntaxFactory.LiteralExpression(SyntaxKind.FalseLiteralExpression));

                    doStatement = doStatement.WithLeadingTrivia(sw.GetLeadingTrivia().Concat(doStatement.GetLeadingTrivia())).WithTrailingTrivia(sw.GetTrailingTrivia());
                    return(doStatement.NormalizeWhitespace());
                }
                catch (Exception e)
                {
                    throw new ReplacerException(sw, e);
                }
            });

            return(root);
        }
示例#11
0
        public SyntaxNode InsertVariables(SyntaxNode root, SemanticModel model, SharpSixRewriter rewriter)
        {
            var tuples = root
                         .DescendantNodes()
                         .OfType <TupleExpressionSyntax>()
                         .Where(e => e.Parent is AssignmentExpressionSyntax ae && ae.Left == e || e.Parent is ForEachVariableStatementSyntax fe && fe.Variable == e);

            var updatedStatements = new Dictionary <StatementSyntax, List <LocalDeclarationStatementSyntax> >();

            foreach (var tuple in tuples)
            {
                try
                {
                    var beforeStatement = tuple.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                    if (beforeStatement != null)
                    {
                        foreach (var arg in tuple.Arguments)
                        {
                            if (arg.Expression is DeclarationExpressionSyntax de)
                            {
                                var designation = de.Designation as SingleVariableDesignationSyntax;

                                if (designation != null)
                                {
                                    var locals   = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();
                                    var typeInfo = model.GetTypeInfo(de).Type;
                                    var varDecl  = SyntaxFactory.VariableDeclaration(SyntaxHelper.GenerateTypeSyntax(typeInfo, model, arg.Expression.GetLocation().SourceSpan.Start, rewriter)).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                                                                                                                  SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(designation.Identifier.ValueText))
                                                                                                                                                                                                                  ));

                                    locals.Add(SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n")));

                                    updatedStatements[beforeStatement] = locals;
                                }
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(tuple, e);
                }
            }

            var parenthesized = root
                                .DescendantNodes()
                                .OfType <ParenthesizedVariableDesignationSyntax>()
                                .Where(e => e.Parent is DeclarationExpressionSyntax && e.Parent.Parent is AssignmentExpressionSyntax ae && ae.Left == e.Parent ||
                                       e.Parent is DeclarationExpressionSyntax && e.Parent.Parent is ForEachVariableStatementSyntax fe && fe.Variable == e.Parent);

            foreach (var p in parenthesized)
            {
                try
                {
                    var beforeStatement = p.Ancestors().OfType <StatementSyntax>().FirstOrDefault();
                    var declaration     = (DeclarationExpressionSyntax)p.Parent;
                    if (beforeStatement != null)
                    {
                        var typeInfo            = model.GetTypeInfo(declaration).Type;
                        List <TypeSyntax> types = new List <TypeSyntax>();
                        if (typeInfo.IsTupleType)
                        {
                            var elements = ((INamedTypeSymbol)typeInfo).TupleElements;
                            foreach (var el in elements)
                            {
                                types.Add(SyntaxHelper.GenerateTypeSyntax(el.Type, model, declaration.GetLocation().SourceSpan.Start, rewriter));
                            }
                        }
                        else
                        {
                            continue;
                        }

                        int idx = 0;
                        foreach (var v in p.Variables)
                        {
                            var designation = v as SingleVariableDesignationSyntax;

                            if (designation != null)
                            {
                                var locals = updatedStatements.ContainsKey(beforeStatement) ? updatedStatements[beforeStatement] : new List <LocalDeclarationStatementSyntax>();

                                var varDecl = SyntaxFactory.VariableDeclaration(types[idx++]).WithVariables(SyntaxFactory.SingletonSeparatedList <VariableDeclaratorSyntax>(
                                                                                                                SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(designation.Identifier.ValueText))
                                                                                                                ));

                                locals.Add(SyntaxFactory.LocalDeclarationStatement(varDecl).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace("\n")));

                                updatedStatements[beforeStatement] = locals;
                            }
                        }
                    }
                }
                catch (Exception e)
                {
                    throw new ReplacerException(p, e);
                }
            }

            var annotated = new Dictionary <SyntaxAnnotation, List <LocalDeclarationStatementSyntax> >();

            root = root.ReplaceNodes(updatedStatements.Keys, (n1, n2) =>
            {
                var annotation        = new SyntaxAnnotation();
                annotated[annotation] = updatedStatements[n1];

                n2 = n2.WithAdditionalAnnotations(annotation);
                return(n2);
            });

            foreach (var annotation in annotated.Keys)
            {
                var annotatedNode = root.GetAnnotatedNodes(annotation).First();
                var varStatements = annotated[annotation];

                if (annotatedNode is ForEachVariableStatementSyntax fe)
                {
                    varStatements[varStatements.Count - 1] = varStatements.Last().WithAdditionalAnnotations(new SyntaxAnnotation("last_variable"));
                    var list = new List <StatementSyntax>(varStatements);

                    if (fe.Statement is BlockSyntax b)
                    {
                        list.AddRange(b.Statements);
                    }
                    else
                    {
                        list.Add(fe.Statement);
                    }

                    root = root.ReplaceNode(annotatedNode, fe.WithStatement(SyntaxFactory.Block(list)).NormalizeWhitespace());
                }
                else if (annotatedNode.Parent is BlockSyntax || !(annotatedNode is StatementSyntax))
                {
                    root = root.InsertNodesBefore(annotatedNode, varStatements);
                }
                else
                {
                    var list = new List <StatementSyntax>(varStatements);
                    list.Add((StatementSyntax)annotatedNode);
                    root = root.ReplaceNode(annotatedNode, SyntaxFactory.Block(list).NormalizeWhitespace());
                }
            }

            return(root);
        }
示例#12
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model, Func <SyntaxNode, Tuple <SyntaxTree, SemanticModel> > updater, SharpSixRewriter rewriter)
        {
            root = InsertVariables(root, model, rewriter);
            var tuple = updater(root);

            root  = tuple.Item1.GetRoot();
            model = tuple.Item2;

            root  = ReplaceDeconstructions(root, model);
            tuple = updater(root);
            root  = tuple.Item1.GetRoot();
            model = tuple.Item2;

            root = ReplaceForeachDeconstructions(root, model);

            return(root);
        }
示例#13
0
        public static TypeSyntax GenerateTypeSyntax(ITypeSymbol type, SemanticModel model, int pos, SharpSixRewriter rewriter)
        {
            if (type.IsTupleType)
            {
                var elements = ((INamedTypeSymbol)type).TupleElements;
                var types    = new List <TypeSyntax>();
                foreach (var el in elements)
                {
                    types.Add(SyntaxHelper.GenerateTypeSyntax(el.Type, model, pos, rewriter));
                }

                return(SyntaxFactory.GenericName(SyntaxFactory.Identifier("System.ValueTuple"), SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList <TypeSyntax>(types))));
            }

            var typeName = type.FullyQualifiedName(false);

            if (rewriter.usingStaticNames.Any(n => typeName.StartsWith(n + '.')))
            {
                return(SyntaxFactory.ParseTypeName(type.ToDisplayString()));
            }
            else if (type is INamedTypeSymbol namedType && namedType.IsGenericType)
            {
                var elements = namedType.TypeArguments;
                var types    = new List <TypeSyntax>();
                foreach (var el in elements)
                {
                    types.Add(SyntaxHelper.GenerateTypeSyntax(el, model, pos, rewriter));
                }

                if (type.OriginalDefinition != null && type.OriginalDefinition.SpecialType == SpecialType.System_Nullable_T)
                {
                    return(SyntaxFactory.IdentifierName(type.ToMinimalDisplayString(
                                                            model,
                                                            pos,
                                                            new SymbolDisplayFormat(
                                                                genericsOptions: SymbolDisplayGenericsOptions.None
                                                                )
                                                            )));
                }

                if (types.Count > 0)
                {
                    string gtypeName;
                    if (type.ContainingType != null)
                    {
                        var parent = SyntaxHelper.GenerateTypeSyntax(type.ContainingType, model, pos, rewriter);
                        var name   = type.Name;
                        gtypeName = SyntaxFactory.QualifiedName((NameSyntax)parent, SyntaxFactory.IdentifierName(name)).ToString();
                    }
                    else
                    {
                        gtypeName = type.ToMinimalDisplayString(
                            model,
                            pos,
                            new SymbolDisplayFormat(
                                genericsOptions: SymbolDisplayGenericsOptions.None
                                )
                            );
                    }

                    if (model != null)
                    {
                        var ai = model.GetSpeculativeAliasInfo(pos, SyntaxFactory.IdentifierName(gtypeName), SpeculativeBindingOption.BindAsTypeOrNamespace);

                        if (ai != null && ai.Name == gtypeName)
                        {
                            return(SyntaxFactory.ParseTypeName(gtypeName));
                        }
                    }

                    return(SyntaxFactory.GenericName(
                               SyntaxFactory.Identifier(gtypeName),
                               SyntaxFactory.TypeArgumentList(
                                   SyntaxFactory.SeparatedList <TypeSyntax>(types)
                                   )
                               ));
                }
            }

            if (type.ContainingType != null && type.Kind != SymbolKind.TypeParameter)
            {
                var parent = SyntaxHelper.GenerateTypeSyntax(type.ContainingType, model, pos, rewriter);
                var name   = type.Name;
                return(SyntaxFactory.QualifiedName((NameSyntax)parent, SyntaxFactory.IdentifierName(name)));
            }

            return(SyntaxFactory.ParseTypeName(type.ToMinimalDisplayString(model, pos)));
        }
示例#14
0
        public SyntaxNode Replace(SyntaxNode root, SemanticModel model, SharpSixRewriter rewriter)
        {
            var localFns       = root.DescendantNodes().OfType <LocalFunctionStatementSyntax>();
            var updatedBlocks  = new Dictionary <SyntaxNode, List <StatementSyntax> >();
            var initForBlocks  = new Dictionary <SyntaxNode, List <StatementSyntax> >();
            var updatedClasses = new Dictionary <TypeDeclarationSyntax, List <DelegateDeclarationSyntax> >();

            foreach (var fn in localFns)
            {
                try
                {
                    var parentNode      = fn.Parent;
                    var usage           = GetFirstUsageLocalFunc(model, fn, parentNode);
                    var beforeStatement = usage?.Ancestors().OfType <StatementSyntax>().FirstOrDefault(ss => ss.Parent == parentNode);

                    if (beforeStatement is LocalFunctionStatementSyntax beforeFn)
                    {
                        List <SyntaxNode> ignore = new List <SyntaxNode>();
                        var usageFn           = usage;
                        var beforeStatementFn = beforeStatement;
                        while (beforeStatementFn != null && beforeStatementFn is LocalFunctionStatementSyntax)
                        {
                            ignore.Add(usageFn);
                            usageFn           = GetFirstUsageLocalFunc(model, fn, parentNode, ignore);
                            beforeStatementFn = usageFn?.Ancestors().OfType <StatementSyntax>().FirstOrDefault(ss => ss.Parent == parentNode);
                        }

                        usage           = GetFirstUsageLocalFunc(model, beforeFn, parentNode);
                        beforeStatement = usage?.Ancestors().OfType <StatementSyntax>().FirstOrDefault(ss => ss.Parent == parentNode);

                        if (beforeStatementFn != null && (beforeStatement == null || beforeStatementFn.SpanStart < beforeStatement.SpanStart))
                        {
                            beforeStatement = beforeStatementFn;
                        }
                    }

                    var customDelegate = false;

                    if (fn.TypeParameterList != null && fn.TypeParameterList.Parameters.Count > 0)
                    {
                        customDelegate = true;
                    }
                    else
                    {
                        foreach (var prm in fn.ParameterList.Parameters)
                        {
                            if (prm.Default != null)
                            {
                                customDelegate = true;
                                break;
                            }

                            foreach (var modifier in prm.Modifiers)
                            {
                                var kind = modifier.Kind();
                                if (kind == SyntaxKind.RefKeyword ||
                                    kind == SyntaxKind.OutKeyword ||
                                    kind == SyntaxKind.ParamsKeyword)
                                {
                                    customDelegate = true;
                                    break;
                                }
                            }

                            if (customDelegate)
                            {
                                break;
                            }
                        }
                    }

                    var returnType = fn.ReturnType.WithoutLeadingTrivia().WithoutTrailingTrivia();
                    var isVoid     = returnType is PredefinedTypeSyntax ptsInstance && ptsInstance.Keyword.Kind() == SyntaxKind.VoidKeyword;

                    TypeSyntax varType;

                    if (customDelegate)
                    {
                        var typeDecl  = parentNode.Ancestors().OfType <TypeDeclarationSyntax>().FirstOrDefault();
                        var delegates = updatedClasses.ContainsKey(typeDecl) ? updatedClasses[typeDecl] : new List <DelegateDeclarationSyntax>();
                        var name      = $"___{fn.Identifier.ValueText}_Delegate_{delegates.Count}";
                        var delDecl   = SyntaxFactory.DelegateDeclaration(returnType, SyntaxFactory.Identifier(name))
                                        .WithModifiers(SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.PrivateKeyword)))
                                        .WithParameterList(fn.ParameterList).NormalizeWhitespace();
                        delegates.Add(delDecl);
                        updatedClasses[typeDecl] = delegates;

                        varType = SyntaxFactory.IdentifierName(name);
                    }
                    else if (isVoid)
                    {
                        if (fn.ParameterList.Parameters.Count == 0)
                        {
                            varType = SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Action"));
                        }
                        else
                        {
                            varType = SyntaxFactory.QualifiedName
                                      (
                                SyntaxFactory.IdentifierName("System"),
                                SyntaxFactory.GenericName("Action").WithTypeArgumentList
                                (
                                    SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(fn.ParameterList.Parameters.Select(p => p.Type)))
                                )
                                      );
                        }
                    }
                    else
                    {
                        if (fn.ParameterList.Parameters.Count == 0)
                        {
                            varType = SyntaxFactory.QualifiedName(
                                SyntaxFactory.IdentifierName("System"),
                                SyntaxFactory.GenericName("Func").WithTypeArgumentList(
                                    SyntaxFactory.TypeArgumentList(SyntaxFactory.SingletonSeparatedList(returnType))
                                    )
                                );
                        }
                        else
                        {
                            varType = SyntaxFactory.QualifiedName
                                      (
                                SyntaxFactory.IdentifierName("System"),
                                SyntaxFactory.GenericName("Func").WithTypeArgumentList
                                (
                                    SyntaxFactory.TypeArgumentList(
                                        SyntaxFactory.SeparatedList(
                                            fn.ParameterList.Parameters.Select(p => p.Type).Concat(
                                                new TypeSyntax[] { returnType }
                                                )
                                            )
                                        )
                                )
                                      );
                        }
                    }

                    List <ParameterSyntax> prms = new List <ParameterSyntax>();

                    if (customDelegate)
                    {
                        foreach (var prm in fn.ParameterList.Parameters)
                        {
                            var newPrm = prm.WithDefault(null);
                            var idx    = newPrm.Modifiers.IndexOf(SyntaxKind.ParamsKeyword);

                            if (idx > -1)
                            {
                                newPrm = newPrm.WithModifiers(newPrm.Modifiers.RemoveAt(idx));
                            }

                            prms.Add(newPrm);
                        }
                    }
                    else
                    {
                        foreach (var prm in fn.ParameterList.Parameters)
                        {
                            prms.Add(SyntaxFactory.Parameter(prm.Identifier));
                        }
                    }

                    var initVar = SyntaxFactory.LocalDeclarationStatement(SyntaxFactory.VariableDeclaration(varType).WithVariables(
                                                                              SyntaxFactory.SingletonSeparatedList(
                                                                                  SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier(fn.Identifier.ValueText)).WithInitializer
                                                                                  (
                                                                                      SyntaxFactory.EqualsValueClause(SyntaxFactory.LiteralExpression(SyntaxKind.NullLiteralExpression))
                                                                                  )
                                                                                  )
                                                                              )).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace(Emitter.NEW_LINE));

                    var assignment = SyntaxFactory.ExpressionStatement(SyntaxFactory.AssignmentExpression(SyntaxKind.SimpleAssignmentExpression,
                                                                                                          SyntaxFactory.IdentifierName(fn.Identifier.ValueText),
                                                                                                          SyntaxFactory.ParenthesizedLambdaExpression(fn.Body ?? (CSharpSyntaxNode)fn.ExpressionBody.Expression).WithParameterList(
                                                                                                              SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(prms))
                                                                                                              )
                                                                                                          )).NormalizeWhitespace().WithTrailingTrivia(SyntaxFactory.Whitespace(Emitter.NEW_LINE));

                    List <StatementSyntax> statements = null;

                    if (updatedBlocks.ContainsKey(parentNode))
                    {
                        statements = updatedBlocks[parentNode];
                    }
                    else
                    {
                        if (parentNode is BlockSyntax bs)
                        {
                            statements = bs.Statements.ToList();
                        }
                        else if (parentNode is SwitchSectionSyntax sss)
                        {
                            statements = sss.Statements.ToList();
                        }
                    }

                    var fnIdx = statements.IndexOf(fn);
                    statements.Insert(beforeStatement != null ? statements.IndexOf(beforeStatement) : Math.Max(0, fnIdx), assignment);
                    updatedBlocks[parentNode] = statements;

                    statements = initForBlocks.ContainsKey(parentNode) ? initForBlocks[parentNode] : new List <StatementSyntax>();
                    statements.Insert(0, initVar);
                    initForBlocks[parentNode] = statements;
                }
                catch (Exception e)
                {
                    throw new ReplacerException(fn, e);
                }
            }

            foreach (var key in initForBlocks.Keys)
            {
                updatedBlocks[key] = initForBlocks[key].Concat(updatedBlocks[key]).ToList();
            }

            if (updatedClasses.Count > 0)
            {
                root = root.ReplaceNodes(updatedClasses.Keys, (t1, t2) =>
                {
                    var members = updatedClasses[t1].ToArray();

                    t1 = t1.ReplaceNodes(updatedBlocks.Keys, (b1, b2) => {
                        SyntaxNode result = b1 is SwitchSectionSyntax sss ? sss.WithStatements(SyntaxFactory.List(updatedBlocks[b1])) : (SyntaxNode)(((BlockSyntax)b1).WithStatements(SyntaxFactory.List(updatedBlocks[b1])));
                        return(result);
                    });

                    var cls = t1 as ClassDeclarationSyntax;
                    if (cls != null)
                    {
                        return(cls.AddMembers(members));
                    }

                    var structDecl = t2 as StructDeclarationSyntax;
                    if (structDecl != null)
                    {
                        return(structDecl.AddMembers(members));
                    }

                    return(t1);
                });
            }
            else if (updatedBlocks.Count > 0)
            {
                root = root.ReplaceNodes(updatedBlocks.Keys, (b1, b2) => {
                    SyntaxNode result = b1 is SwitchSectionSyntax sss ? sss.WithStatements(SyntaxFactory.List(updatedBlocks[b1])) : (SyntaxNode)(((BlockSyntax)b1).WithStatements(SyntaxFactory.List(updatedBlocks[b1])));
                    return(result);
                });
            }

            root = root.RemoveNodes(root.DescendantNodes().OfType <LocalFunctionStatementSyntax>(), SyntaxRemoveOptions.KeepTrailingTrivia | SyntaxRemoveOptions.KeepLeadingTrivia);

            return(root);
        }
示例#15
0
 public static GenericNameSyntax GenerateGenericName(SyntaxToken name, IEnumerable <ITypeSymbol> types, SemanticModel model, int pos, SharpSixRewriter rewriter)
 {
     return(SyntaxFactory.GenericName(name, SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(types.Select((type) => GenerateTypeSyntax(type, model, pos, rewriter))))));
 }
        protected void BuildSyntaxTree()
        {
            this.Log.Info("Building syntax tree...");

            var rewriter = new SharpSixRewriter(this);

            for (int i = 0; i < this.SourceFiles.Count; i++)
            {
                var fileName = this.SourceFiles[i];

                this.Log.Trace("Source file " + (fileName ?? string.Empty) + " ...");

                var parser = new ICSharpCode.NRefactory.CSharp.CSharpParser();

                if (this.DefineConstants != null && this.DefineConstants.Count > 0)
                {
                    foreach (var defineConstant in this.DefineConstants)
                    {
                        parser.CompilerSettings.ConditionalSymbols.Add(defineConstant);
                    }
                }

                var syntaxTree = parser.Parse(rewriter.Rewrite(i), fileName);
                syntaxTree.FileName = fileName;
                //var syntaxTree = parser.Parse(reader, fileName);
                this.Log.Trace("\tParsing syntax tree done");

                if (parser.HasErrors)
                {
                    foreach (var error in parser.Errors)
                    {
                        throw new EmitterException(syntaxTree, string.Format("Parsing error in a file {0} {2}: {1}", fileName, error.Message, error.Region.Begin.ToString()));
                    }
                }

                var expandResult = new QueryExpressionExpander().ExpandQueryExpressions(syntaxTree);
                this.Log.Trace("\tExpanding query expressions done");

                syntaxTree = (expandResult != null ? (SyntaxTree)expandResult.AstNode : syntaxTree);

                var emptyLambdaDetecter = new EmptyLambdaDetecter();
                syntaxTree.AcceptVisitor(emptyLambdaDetecter);
                this.Log.Trace("\tAccepting lambda detector visitor done");

                if (emptyLambdaDetecter.Found)
                {
                    var fixer   = new EmptyLambdaFixer();
                    var astNode = syntaxTree.AcceptVisitor(fixer);
                    this.Log.Trace("\tAccepting lambda fixer visitor done");
                    syntaxTree          = (astNode != null ? (SyntaxTree)astNode : syntaxTree);
                    syntaxTree.FileName = fileName;
                }

                var f = new ParsedSourceFile(syntaxTree, new CSharpUnresolvedFile
                {
                    FileName = fileName
                });
                this.ParsedSourceFiles.Add(f);

                var tcv = new TypeSystemConvertVisitor(f.ParsedFile);
                f.SyntaxTree.AcceptVisitor(tcv);
                this.Log.Trace("\tAccepting type system convert visitor done");

                this.Log.Trace("Source file " + (fileName ?? string.Empty) + " done");
            }

            this.Log.Info("Building syntax tree done");
        }
示例#17
0
 public SyntaxNode Replace(SyntaxNode root, SemanticModel model, SharpSixRewriter rewriter)
 {
     root = InsertVariables(root, model);
     return(ReplacePatterns(root, model));
 }