Пример #1
0
        //server compilation
        private static SyntaxNode CompileServer(SyntaxNode node, Scope scope, SyntacticalExtension <SyntaxNode> data)
        {
            Debug.Assert(node is MethodDeclarationSyntax);
            var methodSyntax = node as MethodDeclarationSyntax;

            var mainServer = new ServerModel();

            if (!parseMainServer(methodSyntax, mainServer))
            {
                return(node); //errors
            }
            //main server class
            var configurationClass = Templates
                                     .ConfigClass
                                     .Get <ClassDeclarationSyntax>(data.Identifier);

            configurationClass = configurationClass
                                 .ReplaceNodes(configurationClass
                                               .DescendantNodes()
                                               .OfType <MethodDeclarationSyntax>(),
                                               (on, nn) =>
            {
                var methodName = nn.Identifier.ToString();
                switch (methodName)
                {
                case "Deploy":
                    return(nn.AddBodyStatements(
                               mainServer
                               .Nodes
                               .SelectMany(serverNode => serverNode.DeployStatements)
                               .Union(
                                   mainServer.DeployStatements)
                               .ToArray()));

                case "Start":
                    return(nn.AddBodyStatements(mainServer.StartStatements.ToArray()));

                case "StartNodes":
                    return(nn.AddBodyStatements(
                               mainServer
                               .Nodes
                               .Select(serverNode => Templates
                                       .NodeInvocation
                                       .Get <StatementSyntax>(serverNode.ServerId))
                               .ToArray()));

                case "RemoteTypes":
                    var initializer = Templates
                                      .RemoteTypes
                                      .DescendantNodes()
                                      .OfType <InitializerExpressionSyntax>()
                                      .Single();

                    return(nn.AddBodyStatements(Templates
                                                .RemoteTypes
                                                .ReplaceNode(
                                                    initializer,
                                                    initializer.AddExpressions(mainServer
                                                                               .Nodes
                                                                               .SelectMany(serverNode => serverNode.HostedClasses)
                                                                               .Select(type => CSharp.TypeOfExpression(type))
                                                                               .ToArray()))));

                case "NodeCount":
                    return(nn.AddBodyStatements(CSharp
                                                .ReturnStatement(CSharp.ParseExpression(
                                                                     mainServer.Nodes.Count.ToString()))));
                }

                throw new NotImplementedException();
            });

            //add a method per node which will be invoked when starting
            configurationClass = configurationClass
                                 .AddMembers(mainServer
                                             .Nodes
                                             .Select(serverNode =>
            {
                var hostedTypes = Templates
                                  .TypeArray
                                  .WithInitializer(CSharp.InitializerExpression(
                                                       SyntaxKind.ArrayInitializerExpression, CSharp.SeparatedList <ExpressionSyntax>(
                                                           serverNode
                                                           .HostedClasses
                                                           .Select(type => CSharp.TypeOfExpression(type)))));

                return(Templates
                       .NodeMethod
                       .Get <MethodDeclarationSyntax>(
                           serverNode.ServerId,
                           hostedTypes)
                       .AddBodyStatements(serverNode
                                          .StartStatements
                                          .ToArray()));
            })
                                             .ToArray());


            //apply changes
            var document = scope.GetDocument();

            document.change(node.Parent, RoslynCompiler.AddType(configurationClass));
            document.change(node.Parent, RoslynCompiler.RemoveMember(node));
            return(node); //untouched, it will be removed
        }