コード例 #1
0
ファイル: Extension.cs プロジェクト: tylike/Excess
        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)));
        }
コード例 #2
0
        private static SyntaxNode CompileService(SyntaxNode node, Scope scope)
        {
            var @class = (node as ClassDeclarationSyntax)
                         .AddAttributeLists(CSharp.AttributeList(CSharp.SeparatedList(new[] { CSharp
                                                                                              .Attribute(CSharp
                                                                                                         .ParseName("Service"),
                                                                                                         CSharp.ParseAttributeArgumentList(
                                                                                                             $"(id : \"{Guid.NewGuid()}\")")) })));

            var options = new Options();

            return(ConcurrentExtension.CompileClass(options)(@class, scope));
        }
コード例 #3
0
ファイル: Extension.cs プロジェクト: tylike/Excess
        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));
        }
コード例 #4
0
ファイル: Class.cs プロジェクト: tylike/Excess
        private ClassDeclarationSyntax addAttribute(ClassDeclarationSyntax @class, string attributeName, bool optional)
        {
            if (@class.AttributeLists.Any(attrList => attrList
                                          .Attributes
                                          .Any(attr => attr.Name.ToString() == attributeName)))
            {
                return(@class);
            }

            return(@class
                   .AddAttributeLists(CSharp.AttributeList(CSharp.SeparatedList(new[] { CSharp
                                                                                        .Attribute(CSharp
                                                                                                   .ParseName(attributeName), optional
                            ? Templates.GuidAttributeArgument(optional: true)
                            : Templates.GuidAttributeArgument(optional: false)) }))));
        }