Ejemplo n.º 1
0
        private static ClassDeclarationSyntax LinkNode(ServerInstance instance, out StatementSyntax appStatement)
        {
            appStatement = Templates.CallStartNode.Get <StatementSyntax>(instance.Id); //td:
            var statements = new List <StatementSyntax>();

            var only = Templates
                       .StringArray
                       .Get <ArrayCreationExpressionSyntax>()
                       .WithInitializer(StringArrayInitializer(instance.HostedClasses));

            statements.Add(Templates
                           .StartNetMQServer
                           .Get <StatementSyntax>(
                               Roslyn.Quoted(instance.Host.Address),
                               Roslyn.Quoted(instance.Parent.Identity),
                               Roslyn.Constant(instance.Threads),
                               only,
                               instance.Id));

            var result = Templates
                         .ServerInstance
                         .Get <ClassDeclarationSyntax>(instance.Id, Roslyn.Quoted(instance.Id));

            var start = result
                        .DescendantNodes()
                        .OfType <MethodDeclarationSyntax>()
                        .Where(method => method.Identifier.ToString() == "Run" &&
                               method.ParameterList.Parameters.Count == 3)
                        .Single();

            return(result
                   .ReplaceNode(start, start
                                .AddBodyStatements(statements.ToArray())));
        }
Ejemplo n.º 2
0
 public static InitializerExpressionSyntax StringArrayInitializer(IEnumerable <string> values)
 {
     return(CSharp.InitializerExpression(
                SyntaxKind.ArrayInitializerExpression,
                CSharp.SeparatedList(values
                                     .Select(value => Roslyn.Quoted(value)))));
 }
Ejemplo n.º 3
0
        private static MethodDeclarationSyntax createRemoteMethod(MethodDeclarationSyntax method)
        {
            var original = method;

            var args = CSharp
                       .AnonymousObjectCreationExpression(CSharp.SeparatedList(method
                                                                               .ParameterList
                                                                               .Parameters
                                                                               .Select(parameter =>
            {
                var identifierName = CSharp.IdentifierName(parameter.Identifier);
                return(CSharp.AnonymousObjectMemberDeclarator(
                           CSharp.NameEquals(identifierName),
                           identifierName));
            })));

            var value = original
                        .ReturnType.ToString() == "void"
                ? Roslyn.@null
                : Templates
                        .RemoteResult
                        .Get <ExpressionSyntax>(original.ReturnType);

            return(method
                   .WithModifiers(CSharp.TokenList())
                   .AddModifiers(
                       CSharp.Token(SyntaxKind.ProtectedKeyword),
                       CSharp.Token(SyntaxKind.OverrideKeyword))
                   .WithBody(Templates
                             .RemoteInternalMethod
                             .Get <BlockSyntax>(
                                 Roslyn.Quoted(original.Identifier.ToString()),
                                 args,
                                 value)));
        }
Ejemplo n.º 4
0
        private static IEnumerable <StatementSyntax> ProcessScopeStatements(SyntaxList <StatementSyntax> statements)
        {
            yield return(Templates.NewScope);

            foreach (var statement in statements)
            {
                if (statement is LocalDeclarationStatementSyntax)
                {
                    //changes to the scope, again expressed as variables
                    var localDeclaration = statement as LocalDeclarationStatementSyntax;
                    var type             = localDeclaration.Declaration.Type;

                    Debug.Assert(localDeclaration.Declaration.Variables.Count == 1); //td: for now
                    var variable = localDeclaration.Declaration.Variables.Single();
                    if (variable.Initializer != null)
                    {
                        yield return(statement);

                        yield return(Templates.AddToNewScope
                                     .Get <StatementSyntax>(
                                         Roslyn.Quoted(variable.Identifier.ToString()),
                                         CSharp.IdentifierName(variable.Identifier)));
                    }
                    else
                    {
                        //td: error, should set values
                    }
                }
                else if (statement is ExpressionStatementSyntax)
                {
                    //invocations to happen on a different context
                    var invocation = (statement as ExpressionStatementSyntax)
                                     .Expression as InvocationExpressionSyntax;

                    if (invocation != null)
                    {
                        if (invocation.Expression is MemberAccessExpressionSyntax)
                        {
                            //td: error, only namspace function calls?
                        }
                        else
                        {
                            yield return(statement.ReplaceNode(invocation, invocation
                                                               .AddArgumentListArguments(CSharp.Argument(Templates
                                                                                                         .NewScopeValue))));
                        }
                    }
                    else
                    {
                        //td: error, bad invocation
                    }
                }
                else
                {
                    //td: error, only variables and invocations
                }
            }
        }
Ejemplo n.º 5
0
        private static MethodDeclarationSyntax concurrentMethod(Class ctx, MethodDeclarationSyntax method, bool forever = false)
        {
            var name = method.Identifier.ToString();

            var body             = method.Body;
            var returnStatements = body
                                   .DescendantNodes()
                                   .OfType <ReturnStatementSyntax>();

            var lastReturn = body.Statements.LastOrDefault() as ReturnStatementSyntax;

            if (returnStatements.Any())
            {
                body = body
                       .ReplaceNodes(returnStatements,
                                     (on, nn) => Templates
                                     .ExpressionReturn
                                     .Get <StatementSyntax>(nn.Expression == null || nn.Expression.IsMissing
                            ? Roslyn.@null
                            : nn.Expression,
                                                            Roslyn.Quoted(method.Identifier.ToString())));
            }

            if (forever)
            {
                body = CSharp.Block(
                    CSharp.ForStatement(body));
            }
            else if (lastReturn == null)
            {
                body = body.AddStatements(Templates
                                          .ExpressionReturn
                                          .Get <StatementSyntax>(
                                              Roslyn.@null,
                                              Roslyn.Quoted(method.Identifier.ToString())));
            }

            var result = Templates
                         .ConcurrentMethod
                         .Get <MethodDeclarationSyntax>("__concurrent" + name);

            result = result
                     .WithParameterList(method
                                        .ParameterList
                                        .AddParameters(result
                                                       .ParameterList
                                                       .Parameters
                                                       .ToArray()))
                     .WithBody(body);

            ctx.AddMember(result);
            return(result);
        }
Ejemplo n.º 6
0
        private StatementSyntax LinkSignal(IdentifierNameSyntax name, InvocationExpressionSyntax success, InvocationExpressionSyntax failure)
        {
            var signalName = name.ToString();
            var signal     = _class.GetSignal(signalName);

            Debug.Assert(signal != null);

            return(Templates
                   .SignalListener
                   .Get <StatementSyntax>(
                       Roslyn.Quoted(signalName),
                       WrapInLambda(success)));
        }
Ejemplo n.º 7
0
        private static SyntaxNode LinkServerInstance(ServerInstance app, Func <ServerModel, Scope, SyntaxNode> transform, Scope scope)
        {
            //a list of statements and types to be added
            var statements = new List <StatementSyntax>();

            foreach (var node in app.Nodes)
            {
                var appStatement = default(StatementSyntax);
                scope.AddType(LinkNode(node, out appStatement));

                if (appStatement != null)
                {
                    statements.Add(appStatement);
                }
            }

            //create the http start
            //
            var except = Templates
                         .StringArray
                         .Get <ArrayCreationExpressionSyntax>()
                         .WithInitializer(StringArrayInitializer(app
                                                                 .Nodes
                                                                 .SelectMany(node => node.HostedClasses)));

            //find functional filters
            var filters = new List <ExpressionSyntax>();

            if (app.SQL != null)
            {
                var connectionString = default(ExpressionSyntax);
                if (app.SQL.ConnectionString != null)
                {
                    Debug.Assert(app.SQL.ConnectionId == null);
                    connectionString = Roslyn.Quoted(app.SQL.ConnectionString);
                }
                else
                {
                    Debug.Assert(app.SQL.ConnectionId != null);
                    connectionString = Templates
                                       .SqlConnectionStringFromConfig
                                       .Get <ExpressionSyntax>(
                        Roslyn.Quoted(app.SQL.ConnectionId));
                }

                var connectionClass = app.SQL.ConnectionInstantiator ?? "SqlConnection";
                filters.Add(Templates
                            .SqlFilter
                            .Get <ExpressionSyntax>(
                                connectionString,
                                CSharp.IdentifierName(connectionClass)));
            }

            filters.Add(Templates.UserFilter);

            //start the server
            statements.Add(Templates
                           .StartHttpServer
                           .Get <StatementSyntax>(
                               Roslyn.Quoted(app.Host.Address),
                               Roslyn.Quoted(app.Identity),
                               Roslyn.Quoted(app.StaticFiles, escaped: true),
                               Roslyn.Constant(app.Threads),
                               except,
                               Roslyn.Constant(app.Nodes.Count),
                               app.Id,
                               Templates
                               .EmptyArray
                               .WithInitializer(CSharp.InitializerExpression(
                                                    SyntaxKind.ArrayInitializerExpression, CSharp.SeparatedList(
                                                        filters)))));

            //generate configuration class
            var result = Templates
                         .ServerInstance
                         .Get <ClassDeclarationSyntax>(app.Id, Roslyn.Quoted(app.Id));

            var runMethods = result
                             .DescendantNodes()
                             .OfType <MethodDeclarationSyntax>()
                             .Where(method => method.Identifier.ToString() == "Run");

            return(result.ReplaceNodes(runMethods,
                                       (on, nn) => nn.AddBodyStatements(statements.ToArray())));
        }
Ejemplo n.º 8
0
        private static bool compileMethod(MethodDeclarationSyntax methodDeclaration, Class ctx, Scope scope, Options options, bool isSingleton)
        {
            var method = methodDeclaration;
            var name   = method.Identifier.ToString();
            var isMain = name == "main";

            var isProtected = method
                              .Modifiers
                              .Where(m => m.Kind() == SyntaxKind.ProtectedKeyword)
                              .Any();

            var isVisible = isProtected || Roslyn.IsVisible(method);
            var isStatic  = Roslyn.IsStatic(method);

            var hasReturnType = method.ReturnType.ToString() != "void";
            var returnType    = hasReturnType
                ? method.ReturnType
                : Roslyn.boolean;

            var isEmptySignal = method.Body == null ||
                                method.Body.IsMissing;

            if (isEmptySignal)
            {
                if (method.ParameterList.Parameters.Count > 0)
                {
                    scope.AddError("concurrent03", "empty signals cannot contain parameters", method);
                }

                if (method.ReturnType.ToString() != "void")
                {
                    scope.AddError("concurrent04", "empty signals cannot return values", method);
                }

                method = method
                         .WithSemicolonToken(CSharp.MissingToken(SyntaxKind.SemicolonToken))
                         .WithBody(CSharp.Block());
            }

            var cc = parseConcurrentBlock(ctx, method.Body, scope, isStatic);

            if (cc != null)
            {
                method = method.WithBody(cc);
            }

            //remove attributes, until needed
            method = method.WithAttributeLists(CSharp.List <AttributeListSyntax>());

            if (isMain)
            {
                if (ctx.HasMain)
                {
                    scope.AddError("concurrent06", "multiple main methods", method);
                    return(false);
                }

                ctx.HasMain = true;

                var statements  = method.Body.Statements;
                var isContinued = (cc == null) && checkContinued(statements);
                if (isContinued)
                {
                    method = method
                             .WithBody(CSharp.Block(statements
                                                    .Take(statements.Count - 1)));
                }

                var mainMethod = concurrentMethod(ctx, method);

                //hook up our start method
                int currentIndex = 0;
                ctx.Replace(methodDeclaration, Templates
                            .StartObject
                            .Get <MethodDeclarationSyntax>(Templates
                                                           .ConcurrentMain
                                                           .Get <InvocationExpressionSyntax>()
                                                           .WithArgumentList(CSharp.ArgumentList(CSharp.SeparatedList(
                                                                                                     mainMethod
                                                                                                     .ParameterList
                                                                                                     .Parameters
                                                                                                     .Where(param => param.Identifier.ToString() != "__cancellation" &&
                                                                                                            param.Identifier.ToString() != "__success" &&
                                                                                                            param.Identifier.ToString() != "__failure")
                                                                                                     .Select(param => CSharp.Argument(Templates
                                                                                                                                      .StartObjectArgument
                                                                                                                                      .Get <ExpressionSyntax>(
                                                                                                                                          param.Type,
                                                                                                                                          currentIndex++)))
                                                                                                     .Union(new[] {
                    CSharp.Argument(Templates.NullCancelationToken),
                    CSharp.Argument(Roslyn.@null),
                    CSharp.Argument(Roslyn.@null),
                }))))));

                return(false);
            }

            if (isVisible)
            {
                if (isEmptySignal)
                {
                    Debug.Assert(!isStatic); //td: error
                    ctx.AddMember(Templates
                                  .EmptySignalMethod
                                  .Get <MethodDeclarationSyntax>(
                                      "__concurrent" + name,
                                      Roslyn.Quoted(name),
                                      isProtected ? Roslyn.@true : Roslyn.@false));
                }
                else
                {
                    concurrentMethod(ctx, method, asVirtual: options.GenerateRemote);
                }
            }
            else if (cc != null)
            {
                concurrentMethod(ctx, method);
            }
            else if (isEmptySignal)
            {
                ctx.AddMember(Templates
                              .EmptySignalMethod
                              .Get <MethodDeclarationSyntax>(
                                  "__concurrent" + name,
                                  Roslyn.Quoted(name),
                                  isProtected? Roslyn.@true : Roslyn.@false));
            }
            else
            {
                return(false);
            }

            var signal = ctx.AddSignal(name, returnType, isVisible, isStatic);

            if (isVisible)
            {
                method = createPublicSignals(ctx, method, signal, isSingleton);
                if (isSingleton)
                {
                    ctx.Replace(methodDeclaration, method);
                }
            }
            else
            {
                ctx.Replace(methodDeclaration, method
                            .WithBody(CSharp.Block()
                                      .WithStatements(CSharp.List(new[] {
                    isEmptySignal
                                ? Templates.SignalDispatcher.Get <StatementSyntax>(Roslyn.Quoted(method.Identifier.ToString()))
                                : Templates.PrivateSignal
                }))));
                return(false);
            }

            return(true);
        }