//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 }