Beispiel #1
0
        private static ArgumentListSyntax Arguments(ParserRuleContext node)
        {
            var expr = null as ExpressionSyntax;
            var args = null as ArgumentListSyntax;

            if (node.ChildCount == 1)
            {
                expr = visitNode(node.GetRuleContext <ParserRuleContext>(0));
            }
            else
            {
                Debug.Assert(node.ChildCount == 2);
                expr = visitNode(node.GetRuleContext <ParserRuleContext>(1));
                args = Arguments(node.GetRuleContext <ParserRuleContext>(0));
            }

            var arg = CSharp.Argument(expr);

            if (args != null)
            {
                return(args.AddArguments(arg));
            }

            return(CSharp
                   .ArgumentList(CSharp
                                 .SeparatedList(new[] { arg })));
        }
Beispiel #2
0
        private static IEnumerable <MemberDeclarationSyntax> createRemoteConstructors(ClassDeclarationSyntax @class, string typeName)
        {
            var constructor = @class
                              .ChildNodes()
                              .OfType <ConstructorDeclarationSyntax>()
                              .OrderBy(ctor => ctor.ParameterList.Parameters.Count)
                              .FirstOrDefault();

            var result = CSharp.ConstructorDeclaration(typeName)
                         .AddParameterListParameters(CSharp
                                                     .Parameter(CSharp.Identifier("id")).WithType(CSharp.ParseTypeName("Guid")))
                         .WithBody(CSharp.Block(Templates.RemoteIdAssign))
                         .WithModifiers(Roslyn.@public);

            if (constructor != null)
            {
                result = result.WithInitializer(CSharp.ConstructorInitializer(
                                                    SyntaxKind.BaseConstructorInitializer,
                                                    CSharp.ArgumentList(CSharp.SeparatedList(
                                                                            constructor
                                                                            .ParameterList
                                                                            .Parameters
                                                                            .Select(parameter => CSharp.Argument(
                                                                                        CSharp.DefaultExpression(parameter.Type)))))));
            }

            return(new MemberDeclarationSyntax[]
            {
                result
            });
        }
Beispiel #3
0
 private static string argumentsFromParameters(IEnumerable <ParameterSyntax> parameters)
 {
     return(CSharp
            .ArgumentList(CSharp.SeparatedList(
                              parameters
                              .Select(parameter => CSharp.Argument(CSharp.
                                                                   IdentifierName(parameter.Identifier)))))
            .ToString());
 }
Beispiel #4
0
        private static MethodDeclarationSyntax createPublicSignals(Class ctx, MethodDeclarationSyntax method, Signal signal, bool isSingleton)
        {
            var returnType = method.ReturnType.ToString() != "void"
                ? method.ReturnType
                : Roslyn.@object;

            var internalMethod = method.Identifier.ToString();

            if (!internalMethod.StartsWith("__concurrent"))
            {
                internalMethod = "__concurrent" + internalMethod;
            }

            var internalCall = Templates.InternalCall
                               .Get <ExpressionSyntax>(internalMethod);

            internalCall = internalCall
                           .ReplaceNodes(internalCall
                                         .DescendantNodes()
                                         .OfType <InvocationExpressionSyntax>()
                                         .Where(i => i.ArgumentList.Arguments.Count == 3),
                                         (on, nn) => nn
                                         .WithArgumentList(CSharp.ArgumentList(CSharp.SeparatedList(
                                                                                   method.ParameterList.Parameters
                                                                                   .Select(param => CSharp.Argument(CSharp.IdentifierName(
                                                                                                                        param.Identifier)))
                                                                                   .Union(on.ArgumentList.Arguments)))));

            var ps1 = publicSignal(
                method.ParameterList,
                Templates.TaskPublicMethod
                .Get <MethodDeclarationSyntax>(
                    method.Identifier.ToString(),
                    returnType,
                    internalCall));

            var ps2 = publicSignal(
                method.ParameterList,
                Templates.TaskCallbackMethod
                .Get <MethodDeclarationSyntax>(
                    method.Identifier.ToString(),
                    internalCall));

            if (isSingleton)
            {
                ctx.AddMember(singletonPublicSignal(ps1, out ps1));
                ctx.AddMember(singletonPublicSignal(ps2, out ps2));
                ctx.AddMember(singletonPublicSignal(method, out method));
            }

            ctx.AddMember(ps1);
            ctx.AddMember(ps2);
            return(method);
        }
Beispiel #5
0
        private static SyntaxNode CompileFunction(SyntaxNode node, Scope scope)
        {
            var method          = (MethodDeclarationSyntax)node;
            var concurrentClass = method.Identifier.ToString() + "__concurrent";

            //create a concurrent class with the method
            var @class = CSharp.ClassDeclaration(concurrentClass)
                         .AddMembers(method);

            //add it to the parent
            var document = scope.GetDocument();

            document.change(node.Parent, AddFunctionClass(@class));

            //create a substitute call
            var invocation = Templates.FunctionInvocation
                             .Get <ExpressionStatementSyntax>(
                concurrentClass,
                method.Identifier);

            if (method.ParameterList.Parameters.Count > 0)
            {
                var invoke    = (InvocationExpressionSyntax)invocation.Expression;
                var arguments = method.ParameterList
                                .Parameters
                                .Select(parameter => CSharp.Argument(CSharp.IdentifierName(
                                                                         parameter.Identifier)))
                                .Union(invoke.ArgumentList.Arguments);

                invocation = invocation
                             .WithExpression(invoke
                                             .WithArgumentList(CSharp.ArgumentList(CSharp.SeparatedList(
                                                                                       arguments))));
            }

            return(method
                   .AddAttributeLists(CSharp.AttributeList(CSharp.SeparatedList <AttributeSyntax>(new[] {
                CSharp.Attribute(CSharp.ParseName("Concurrent"))
            })))
                   .AddParameterListParameters(Templates
                                               .FunctionParameters
                                               .Parameters
                                               .ToArray())
                   .WithBody(CSharp.Block(invocation)));
        }
Beispiel #6
0
        private static ExpressionSyntax Call(ParserRuleContext node)
        {
            if (node.ChildCount == 1)
            {
                return(Expression(node.GetRuleContext <ParserRuleContext>(0)));
            }

            var expr = visitNode(node.GetRuleContext <ParserRuleContext>(0));
            var args = null as ArgumentListSyntax;

            if (node.ChildCount == 4)
            {
                args = Arguments(node.GetRuleContext <ParserRuleContext>(2));
            }
            else
            {
                args = CSharp.ArgumentList();
            }

            return(CSharp.InvocationExpression(expr, args));
        }
Beispiel #7
0
        private ExpressionSyntax CreateCallback(bool success, bool leftOfParent, SyntaxToken token)
        {
            var arg1 = leftOfParent
                ? success ? Roslyn.@true : Roslyn.@false
                : Roslyn.@null;

            var arg2 = leftOfParent
                ? Roslyn.@null
                : success ? Roslyn.@true : Roslyn.@false;

            var ex = success
                ? Roslyn.@null
                : Templates.FailureParameter;

            return(CSharp
                   .InvocationExpression(CSharp.IdentifierName(token))
                   .WithArgumentList(CSharp.ArgumentList(CSharp.SeparatedList(new[] {
                CSharp.Argument(arg1),
                CSharp.Argument(arg2),
                CSharp.Argument(ex)
            }))));
        }
Beispiel #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);
        }
Beispiel #9
0
        private static SyntaxNode Compile(SyntaxNode node, Scope scope, bool isSingleton, Options options)
        {
            Debug.Assert(node is ClassDeclarationSyntax);
            var @class = (node as ClassDeclarationSyntax)
                         .AddBaseListTypes(
                CSharp.SimpleBaseType(CSharp.ParseTypeName(
                                          "ConcurrentObject")));

            if (options.GenerateInterface)
            {
                @class = @class.AddBaseListTypes(
                    CSharp.SimpleBaseType(CSharp.ParseTypeName(
                                              "I" + (node as ClassDeclarationSyntax).Identifier.ToString())));
            }

            var className = @class.Identifier.ToString();

            var ctx = new Class(className, scope, isSingleton);

            scope.set <Class>(ctx);

            foreach (var member in @class.Members)
            {
                if (member is PropertyDeclarationSyntax)
                {
                    compileProperty(member as PropertyDeclarationSyntax, ctx, scope);
                }
                else if (member is MethodDeclarationSyntax)
                {
                    var method = member as MethodDeclarationSyntax;
                    if (compileMethod(method, ctx, scope, options, isSingleton))
                    {
                        var isVoid   = method.ReturnType.ToString() == "void";
                        var taskArgs = isVoid
                            ? new[]
                        {
                            CSharp.Argument(Templates.NullCancelationToken),
                            CSharp.Argument(Roslyn.@null),
                            CSharp.Argument(Roslyn.@null)
                        }
                            : new[]
                        {
                            CSharp.Argument(Templates.NullCancelationToken)
                        };

                        var taskCall = CSharp
                                       .InvocationExpression(
                            CSharp.IdentifierName(method.Identifier),
                            CSharp.ArgumentList(CSharp.SeparatedList(
                                                    method
                                                    .ParameterList
                                                    .Parameters
                                                    .Select(parameter => CSharp
                                                            .Argument(CSharp.IdentifierName(parameter.Identifier)))
                                                    .Union(
                                                        taskArgs))));

                        var newMethod = method
                                        .AddAttributeLists(CSharp.AttributeList(CSharp.SeparatedList(new[] { CSharp
                                                                                                             .Attribute(CSharp
                                                                                                                        .ParseName("Concurrent")) })))
                                        .WithBody(CSharp.Block()
                                                  .WithStatements(CSharp.List(new[] {
                            isVoid
                                        ? Templates
                            .SynchVoidMethod
                            .Get <StatementSyntax>(taskCall)
                                        : Templates
                            .SynchReturnMethod
                            .Get <StatementSyntax>(taskCall)
                        })));

                        if (isSingleton && ctx.willReplace(method))
                        {
                            //singleton methods must change into __methodName
                            var fs = (newMethod
                                      .Body
                                      .Statements
                                      .First() as ExpressionStatementSyntax)
                                     .Expression as InvocationExpressionSyntax;

                            var newId = "__" + method.Identifier.ToString();
                            newMethod = newMethod
                                        .ReplaceNode(fs, fs.WithExpression(CSharp.IdentifierName(newId)))
                                        .WithIdentifier(CSharp.ParseToken(newId));
                        }

                        ctx.Replace(method, newMethod);
                    }
                }
            }

            //all concurrent compilation has been done, produce
            @class = ctx.Update(@class);

            if (isSingleton)
            {
                @class = @class.AddMembers(
                    Templates.SingletonField
                    .Get <MemberDeclarationSyntax>(@class.Identifier),
                    Templates.SingletonInit
                    .Get <MemberDeclarationSyntax>(@class.Identifier));
            }

            //generate the interface
            if (options.GenerateInterface)
            {
                scope.AddType(CreateInterface(@class));
            }

            if (options.GenerateRemote)
            {
                //add a remote type, to be used with an identity server
                var remoteMethod = null as MethodDeclarationSyntax;
                createRemoteType(@class, scope, out remoteMethod);
                @class = @class.AddMembers(remoteMethod);
            }

            if (options.GenerateID)
            {
                @class = @class.AddMembers(Templates
                                           .ObjectId
                                           .Get <MemberDeclarationSyntax>());
            }

            //schedule linking
            var document = scope.GetDocument();

            return(document.change(@class, Link(ctx), null));
        }
Beispiel #10
0
        private static SyntaxNode ArgumentList(RParser.SublistContext args, Func <ParserRuleContext, Scope, SyntaxNode> transform, Scope scope)
        {
            var nodes = new List <ArgumentSyntax>();

            foreach (var arg in args.sub())
            {
                var argName = null as string;
                var value   = null as ExpressionSyntax;
                if (arg is RParser.SubExpressionContext)
                {
                    value = (ExpressionSyntax)transform((arg as RParser.SubExpressionContext).expr(), scope);
                }
                else if (arg is RParser.SubAssignmentContext)
                {
                    var paramName = (arg as RParser.SubAssignmentContext);
                    argName = paramName.ID().ToString();
                    value   = (ExpressionSyntax)transform(paramName.expr(), scope);
                }
                else if (arg is RParser.SubStringAssignmentContext)
                {
                    var paramName = (arg as RParser.SubStringAssignmentContext);
                    argName = paramName.STRING().ToString();
                    value   = (ExpressionSyntax)transform(paramName.expr(), scope);
                }
                else if (arg is RParser.SubIncompleteNullContext || arg is RParser.SubNullAssignmentContext)
                {
                    throw new NotImplementedException();
                }
                else if (arg is RParser.SubEllipsisContext)
                {
                    throw new NotImplementedException();
                }
                else if (arg is RParser.SubIncompleteAssignmentContext || arg is RParser.SubIncompleteStringContext || arg is RParser.SubIncompleteStringContext)
                {
                    throw new NotImplementedException();
                }
                else if (arg is RParser.SubEmptyContext)
                {
                    continue;
                }
                else
                {
                    Debug.Assert(false);
                }

                Debug.Assert(value != null);
                var result = CSharp.Argument(value);
                if (argName != null)
                {
                    result = result
                             .WithNameColon(CSharp
                                            .NameColon(argName));
                }

                nodes.Add(result);
            }

            return(CSharp
                   .ArgumentList()
                   .WithArguments(CSharp
                                  .SeparatedList(nodes)));
        }