Пример #1
0
        private static SyntaxNode ProcessMemberFunction(SyntaxNode node, Scope scope)
        {
            var document = scope.GetDocument <SyntaxToken, SyntaxNode, SemanticModel>();

            if (node is MethodDeclarationSyntax)
            {
                var method = node as MethodDeclarationSyntax;
                if (method.ReturnType.IsMissing)
                {
                    document.change(method, ReturnType);
                    return(method.WithReturnType(RoslynCompiler.@void));
                }

                return(node);
            }

            //handle functions declared inside code blocks
            var statement = node
                            .AncestorsAndSelf()
                            .OfType <StatementSyntax>()
                            .FirstOrDefault();

            Debug.Assert(statement != null); //td: error, maybe?
            Debug.Assert(statement is ExpressionStatementSyntax);

            var invocation = (statement as ExpressionStatementSyntax)
                             .Expression as InvocationExpressionSyntax;

            Debug.Assert(invocation != null);

            var function = invocation.Expression as IdentifierNameSyntax;

            Debug.Assert(function != null);

            BlockSyntax parent = statement.Parent as BlockSyntax;

            Debug.Assert(parent != null); //td: error, maybe?

            var body = RoslynCompiler.NextStatement(parent, statement) as BlockSyntax;

            if (body == null)
            {
                //td: error, function declaration must be followed by a block of code
                return(node);
            }

            //We are not allowed to modify parents, so schedule the removal of the code
            //And its insertion in the final lambda variable
            document.change(parent, RoslynCompiler.RemoveStatement(body));
            document.change(statement, ProcessCodeFunction(function, body));
            return(node);
        }
Пример #2
0
        private static SyntaxNode ProcessMemberFunction(SyntaxNode node, Scope scope)
        {
            var document = scope.GetDocument <SyntaxToken, SyntaxNode, SemanticModel>();

            if (node is MethodDeclarationSyntax)
            {
                var method = (node as MethodDeclarationSyntax)
                             .AddParameterListParameters(CSharp
                                                         .Parameter(Templates.ScopeToken)
                                                         .WithType(Templates.ScopeType));

                method = MemberFunctionModifiers(method);

                if (method.ReturnType.IsMissing)
                {
                    method = method.WithReturnType(RoslynCompiler.@void);

                    var calculateType = method.Body
                                        .DescendantNodes()
                                        .OfType <ReturnStatementSyntax>()
                                        .Any();

                    var isMember = method.Parent is TypeDeclarationSyntax;
                    if (!isMember)
                    {
                        var service = scope.GetService <SyntaxToken, SyntaxNode, SemanticModel>();
                        return(service.MarkNode(Templates
                                                .NamespaceFunction
                                                .AddMembers((MemberDeclarationSyntax)document.change(
                                                                method,
                                                                LinkNamespaceFunction(calculateType)))));
                    }

                    return(calculateType
                        ? document.change(method, CalculateReturnType)
                        : method);
                }

                return(node);
            }

            //handle functions declared inside code blocks
            var statement = node
                            .AncestorsAndSelf()
                            .OfType <StatementSyntax>()
                            .FirstOrDefault();

            Debug.Assert(statement != null); //td: error, maybe?
            Debug.Assert(statement is ExpressionStatementSyntax);

            var invocation = (statement as ExpressionStatementSyntax)
                             .Expression as InvocationExpressionSyntax;

            Debug.Assert(invocation != null);

            var function = invocation.Expression as IdentifierNameSyntax;

            Debug.Assert(function != null);

            BlockSyntax parent = statement.Parent as BlockSyntax;

            Debug.Assert(parent != null); //td: error, maybe?

            var body = RoslynCompiler.NextStatement(parent, statement) as BlockSyntax;

            if (body == null)
            {
                //td: error, function declaration must be followed by a block of code
                return(node);
            }

            //We are not allowed to modify parents, so schedule the removal of the code
            //And its insertion in the final lambda variable
            document.change(parent, RoslynCompiler.RemoveStatement(body));
            document.change(statement, ProcessCodeFunction(function, body));
            return(node);
        }