Ejemplo n.º 1
0
        private static SyntaxNode ProcessContract(SyntaxNode node, Scope scope, SyntacticalExtension<SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var block = extension.Body as BlockSyntax;
                Debug.Assert(block != null);

                List<StatementSyntax> checks = new List<StatementSyntax>();
                foreach (var st in block.Statements)
                {
                    var stExpression = st as ExpressionStatementSyntax;
                    if (stExpression == null)
                    {
                        scope.AddError("contract01", "contracts only support boolean expressions", st);
                        continue;
                    }

                    var contractCheck = ContractCheck
                        .ReplaceNodes(ContractCheck
                            .DescendantNodes()
                            .OfType<ExpressionSyntax>()
                            .Where(expr => expr.ToString() == "__condition"),

                         (oldNode, newNode) =>
                            stExpression.Expression);

                    checks.Add(contractCheck);
                }

                return CSharp.Block(checks);
            }

            scope.AddError("contract02", "contract cannot return a value", node);
            return node;
        }
Ejemplo n.º 2
0
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            if (node.Declaration.Variables.Count == 1)
            {
                var variable = node
                               .Declaration
                               .Variables[0];

                if (variable.Initializer != null)
                {
                    var call = variable.Initializer.Value as InvocationExpressionSyntax;
                    if (call != null)
                    {
                        SyntacticalExtension <SyntaxNode> extension = codeExtension(call);
                        if (extension != null)
                        {
                            if (extension.Kind != ExtensionKind.Code)
                            {
                                //td: error, incorrect extension (i.e. a code extension being used inside a type)
                                return(node);
                            }

                            _lookahead = CheckCodeExtension(node, extension);
                            return(null);
                        }
                    }
                }
            }

            return(base.VisitLocalDeclarationStatement(node));
        }
Ejemplo n.º 3
0
        private static SyntaxNode ProcessContract(SyntaxNode node, Scope scope, SyntacticalExtension <SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var block = extension.Body as BlockSyntax;
                Debug.Assert(block != null);

                List <StatementSyntax> checks = new List <StatementSyntax>();
                foreach (var st in block.Statements)
                {
                    var stExpression = st as ExpressionStatementSyntax;
                    if (stExpression == null)
                    {
                        scope.AddError("contract01", "contracts only support boolean expressions", st);
                        continue;
                    }

                    var contractCheck = ContractCheck
                                        .ReplaceNodes(ContractCheck
                                                      .DescendantNodes()
                                                      .OfType <ExpressionSyntax>()
                                                      .Where(expr => expr.ToString() == "__condition"),

                                                      (oldNode, newNode) =>
                                                      stExpression.Expression);

                    checks.Add(contractCheck);
                }

                return(CSharp.Block(checks));
            }

            scope.AddError("contract02", "contract cannot return a value", node);
            return(node);
        }
Ejemplo n.º 4
0
 private SyntaxNode typeExtension(SyntaxNode node, SyntacticalExtension <SyntaxNode> extension)
 {
     return(CSharp.ClassDeclaration(extension.Identifier)
            .WithMembers(CSharp.List <MemberDeclarationSyntax>(new[] {
         CSharp.MethodDeclaration(CSharp.ParseTypeName("int"), "myMethod")
         .WithBody((BlockSyntax)extension.Body)
     })));
 }
Ejemplo n.º 5
0
        private static SyntaxNode ProcessSynch(SyntaxNode node, Scope scope, SyntacticalExtension <SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                //td: verify it's inside an asynch
                return(SynchTemplate
                       .ReplaceNodes(SynchTemplate
                                     .DescendantNodes()
                                     .OfType <BlockSyntax>(),
                                     (oldNode, newNode) => extension.Body));
            }

            scope.AddError("synch01", "synch does not return a value", node);
            return(node);
        }
Ejemplo n.º 6
0
        private static SyntaxNode ProcessSynch(SyntaxNode node, Scope scope, SyntacticalExtension<SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                //td: verify it's inside an asynch
                return SynchTemplate
                    .ReplaceNodes(SynchTemplate
                        .DescendantNodes()
                        .OfType<BlockSyntax>(),
                        (oldNode, newNode) => extension.Body);
            }

            scope.AddError("synch01", "synch does not return a value", node);
            return node;
        }
Ejemplo n.º 7
0
        private SyntaxNode memberExtension(SyntaxNode node, SyntacticalExtension <SyntaxNode> extension)
        {
            var memberDecl = node as MethodDeclarationSyntax;

            Assert.IsNotNull(memberDecl);

            return(memberDecl
                   .WithReturnType(CSharp.ParseTypeName("int"))
                   .WithIdentifier(CSharp.ParseToken("anotherName"))
                   .WithParameterList(CSharp.ParameterList())
                   .WithBody(memberDecl.Body
                             .AddStatements(new[] {
                CSharp.ParseStatement("var myFoo = 5;"),
                CSharp.ParseStatement("bar(myFoo);")
            })));
        }
Ejemplo n.º 8
0
        private SyntaxNode codeExtension(SyntaxNode node, SyntacticalExtension <SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var codeBlock = extension.Body as BlockSyntax;
                Assert.IsNotNull(extension.Body);
                return(codeBlock.AddStatements(
                           new[] {
                    CSharp.ParseStatement("var myFoo = 5;"),
                    CSharp.ParseStatement("bar(myFoo);")
                }));
            }

            Assert.AreEqual(extension.Kind, ExtensionKind.Expression);
            return(CSharp.ParseExpression("bar(7)"));
        }
Ejemplo n.º 9
0
        private static SyntaxNode ProcessAsynch(SyntaxNode node, Scope scope, SyntacticalExtension<SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var result = AsynchTemplate
                    .ReplaceNodes(AsynchTemplate
                        .DescendantNodes()
                        .OfType<BlockSyntax>(),
                        (oldNode, newNode) => extension.Body);

                var document = scope.GetDocument<SyntaxToken, SyntaxNode, SemanticModel>();
                document.change(node.Parent, RoslynCompiler.AddStatement(ContextVariable, before: node));

                return result;
            }

            scope.AddError("asynch01", "asynch does not return a value", node);
            return node;
        }
Ejemplo n.º 10
0
        private static SyntaxNode ProcessAsynch(SyntaxNode node, Scope scope, SyntacticalExtension <SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var result = AsynchTemplate
                             .ReplaceNodes(AsynchTemplate
                                           .DescendantNodes()
                                           .OfType <BlockSyntax>(),
                                           (oldNode, newNode) => extension.Body);

                var document = scope.GetDocument <SyntaxToken, SyntaxNode, SemanticModel>();
                document.change(node.Parent, RoslynCompiler.AddStatement(ContextVariable, before: node));

                return(result);
            }

            scope.AddError("asynch01", "asynch does not return a value", node);
            return(node);
        }
Ejemplo n.º 11
0
        public override SyntaxNode VisitIncompleteMember(IncompleteMemberSyntax node)
        {
            SyntacticalExtension <SyntaxNode> extension = typeExtension(node);

            if (extension != null)
            {
                if (extension.Kind == ExtensionKind.Type)
                {
                    _lookahead = MatchTypeExtension(node, extension);

                    return(null); //remove the incomplete member
                }
                else
                {
                    //td: error, incorrect extension (i.e. a code extension being used inside a type)
                    return(null);
                }
            }

            return(node); //error, stop processing
        }
Ejemplo n.º 12
0
        public override SyntaxNode VisitMethodDeclaration(MethodDeclarationSyntax method)
        {
            SyntacticalExtension <SyntaxNode> extension = methodExtension(method);

            if (extension != null)
            {
                switch (extension.Kind)
                {
                case ExtensionKind.Member:
                case ExtensionKind.Type:
                {
                    return(extension.Handler(method, new Scope(_scope), extension));
                }

                default:
                {
                    //td: error, incorrect extension (i.e. a code extension being used inside a type)
                    return(null);
                }
                }
            }

            return(base.VisitMethodDeclaration(method));
        }
Ejemplo n.º 13
0
        //rewriters
        private Func <SyntaxNode, Scope, LookAheadResult> CheckCodeExtension(SyntaxNode original, SyntacticalExtension <SyntaxNode> extension)
        {
            return((node, scope) =>
            {
                var code = node as BlockSyntax;
                if (code == null)
                {
                    return new LookAheadResult {
                        Matched = false
                    }
                }
                ;

                _lookahead = null;
                extension.Body = base.Visit(code);

                SyntaxNode resulSyntaxNode = null;

                if (original is LocalDeclarationStatementSyntax)
                {
                    extension.Kind = ExtensionKind.Expression;

                    resulSyntaxNode = extension.Handler(node, scope, extension);
                    if (!(resulSyntaxNode is ExpressionSyntax))
                    {
                        //td: error, expecting expression
                        return new LookAheadResult {
                            Matched = false
                        };
                    }

                    var localDecl = original as LocalDeclarationStatementSyntax;
                    resulSyntaxNode = localDecl
                                      .WithDeclaration(localDecl.Declaration
                                                       .WithVariables(CSharp.SeparatedList(new[] {
                        localDecl.Declaration.Variables[0]
                        .WithInitializer(localDecl.Declaration.Variables[0].Initializer
                                         .WithValue((ExpressionSyntax)resulSyntaxNode))
                    })))
                                      .WithSemicolonToken(CSharp.ParseToken(";"));
                }
                else if (original is ExpressionStatementSyntax)
                {
                    var exprStatement = original as ExpressionStatementSyntax;
                    var assignment = exprStatement.Expression as AssignmentExpressionSyntax;
                    if (assignment != null)
                    {
                        extension.Kind = ExtensionKind.Expression;
                        resulSyntaxNode = extension.Handler(node, scope, extension);
                        if (!(resulSyntaxNode is ExpressionSyntax))
                        {
                            //td: error, expecting expression
                            return new LookAheadResult {
                                Matched = false
                            };
                        }

                        resulSyntaxNode = exprStatement
                                          .WithExpression(assignment
                                                          .WithRight((ExpressionSyntax)resulSyntaxNode))
                                          .WithSemicolonToken(CSharp.ParseToken(";"));
                    }
                    else
                    {
                        resulSyntaxNode = extension.Handler(node, scope, extension);
                        if (resulSyntaxNode != null)
                        {
                            resulSyntaxNode = RoslynCompiler.UpdateExcessId(resulSyntaxNode, node);
                        }
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }

                return new LookAheadResult
                {
                    Matched = true,
                    Result = resulSyntaxNode,
                };
            });
        }
Ejemplo n.º 14
0
        private SyntaxNode memberExtension(SyntaxNode node, SyntacticalExtension<SyntaxNode> extension)
        {
            var memberDecl = node as MethodDeclarationSyntax;
            Assert.IsNotNull(memberDecl);

            return memberDecl
                .WithReturnType(CSharp.ParseTypeName("int"))
                .WithIdentifier(CSharp.ParseToken("anotherName"))
                .WithParameterList(CSharp.ParameterList())
                .WithBody(memberDecl.Body
                    .AddStatements(new[] {
                        CSharp.ParseStatement("var myFoo = 5;"),
                        CSharp.ParseStatement("bar(myFoo);")}));
        }
Ejemplo n.º 15
0
        private Func <SyntaxNode, Scope, LookAheadResult> MatchTypeExtension(IncompleteMemberSyntax incomplete, SyntacticalExtension <SyntaxNode> extension)
        {
            return((node, scope) =>
            {
                var resulSyntaxNode = node;
                if (node is ClassDeclarationSyntax)
                {
                    ClassDeclarationSyntax clazz = (ClassDeclarationSyntax)node;
                    clazz = clazz
                            .WithAttributeLists(incomplete.AttributeLists)
                            .WithModifiers(incomplete.Modifiers);

                    resulSyntaxNode = extension.Handler(node, scope, extension);
                }

                //td: error?, expecting class
                return new LookAheadResult
                {
                    Matched = resulSyntaxNode != null,
                    Result = resulSyntaxNode
                };
            });
        }
Ejemplo n.º 16
0
        private Func<SyntaxNode, Scope, LookAheadResult> MatchTypeExtension(IncompleteMemberSyntax incomplete, SyntacticalExtension<SyntaxNode> extension)
        {
            return (node, scope) =>
            {
                var resulSyntaxNode = node;
                if (node is ClassDeclarationSyntax)
                {
                    ClassDeclarationSyntax clazz = (ClassDeclarationSyntax)node;
                    clazz = clazz
                        .WithAttributeLists(incomplete.AttributeLists)
                        .WithModifiers(incomplete.Modifiers);

                    resulSyntaxNode = extension.Handler(node, scope, extension);
                }

                //td: error?, expecting class
                return new LookAheadResult
                {
                    Matched = resulSyntaxNode != null,
                    Result = resulSyntaxNode
                };
            };
        }
Ejemplo n.º 17
0
        //rewriters
        private Func<SyntaxNode, Scope, LookAheadResult> CheckCodeExtension(SyntaxNode original, SyntacticalExtension<SyntaxNode> extension)
        {
            return (node, scope) =>
            {
                var code = node as BlockSyntax;
                if (code == null)
                    return new LookAheadResult { Matched = false };

                _lookahead = null;
                extension.Body = base.Visit(code);

                SyntaxNode resulSyntaxNode = null;

                if (original is LocalDeclarationStatementSyntax)
                {
                    extension.Kind = ExtensionKind.Expression;
                    resulSyntaxNode = extension.Handler(node, scope, extension);
                    if (!(resulSyntaxNode is ExpressionSyntax))
                    {
                        //td: error, expecting expression
                        return new LookAheadResult { Matched = false };
                    }

                    var localDecl = original as LocalDeclarationStatementSyntax;
                    resulSyntaxNode = localDecl
                        .WithDeclaration(localDecl.Declaration
                            .WithVariables(CSharp.SeparatedList(new[] {
                                localDecl.Declaration.Variables[0]
                                    .WithInitializer(localDecl.Declaration.Variables[0].Initializer
                                        .WithValue((ExpressionSyntax)resulSyntaxNode))})))
                        .WithSemicolonToken(CSharp.ParseToken(";"));
                }
                else if (original is ExpressionStatementSyntax)
                {
                    var exprStatement = original as ExpressionStatementSyntax;
                    var assignment = exprStatement.Expression as AssignmentExpressionSyntax;
                    if (assignment != null)
                    {
                        extension.Kind = ExtensionKind.Expression;
                        resulSyntaxNode = extension.Handler(node, scope, extension);
                        if (!(resulSyntaxNode is ExpressionSyntax))
                        {
                            //td: error, expecting expression
                            return new LookAheadResult { Matched = false };
                        }

                        resulSyntaxNode = exprStatement
                            .WithExpression(assignment
                                .WithRight((ExpressionSyntax)resulSyntaxNode))
                            .WithSemicolonToken(CSharp.ParseToken(";"));
                    }
                    else
                    {
                        resulSyntaxNode = extension.Handler(node, scope, extension);
                        if (resulSyntaxNode != null)
                            resulSyntaxNode = RoslynCompiler.UpdateExcessId(resulSyntaxNode, node);
                    }
                }
                else
                    throw new NotImplementedException();

                return new LookAheadResult
                {
                    Matched = true,
                    Result = resulSyntaxNode,
                };
            };
        }
Ejemplo n.º 18
0
 private SyntaxNode typeExtension(SyntaxNode node, SyntacticalExtension<SyntaxNode> extension)
 {
     return CSharp.ClassDeclaration(extension.Identifier)
         .WithMembers(CSharp.List<MemberDeclarationSyntax>(new[] {
                 CSharp.MethodDeclaration(CSharp.ParseTypeName("int"), "myMethod")
                     .WithBody((BlockSyntax)extension.Body)
         }));
 }
Ejemplo n.º 19
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
        }
Ejemplo n.º 20
0
        private SyntaxNode codeExtension(SyntaxNode node, SyntacticalExtension<SyntaxNode> extension)
        {
            if (extension.Kind == ExtensionKind.Code)
            {
                var codeBlock = extension.Body as BlockSyntax;
                Assert.IsNotNull(extension.Body);
                return codeBlock.AddStatements(
                    new[] {
                    CSharp.ParseStatement("var myFoo = 5;"),
                    CSharp.ParseStatement("bar(myFoo);")
                });
            }

            Assert.AreEqual(extension.Kind, ExtensionKind.Expression);
            return CSharp.ParseExpression("bar(7)");
        }