コード例 #1
0
ファイル: ExpressionParser.cs プロジェクト: tylike/Excess
        public override SyntaxNode VisitLocalDeclarationStatement(LocalDeclarationStatementSyntax node)
        {
            var awaitExpr      = null as ExpressionSyntax;
            var extraStatement = null as StatementSyntax;

            if (node.Declaration.Variables.Count == 1)
            {
                var variable = node
                               .Declaration
                               .Variables[0];

                var value = variable
                            ?.Initializer
                            ?.Value;

                if (node.Declaration.Type.ToString() == "await")
                {
                    //case: await signal;
                    awaitExpr = CSharp.IdentifierName(variable.Identifier);
                }
                else if (value != null && value is AwaitExpressionSyntax)
                {
                    //case: var a = await b();
                    extraStatement = CSharp
                                     .LocalDeclarationStatement(CSharp.VariableDeclaration(
                                                                    node.Declaration.Type, CSharp.SeparatedList(new[] {
                        CSharp.VariableDeclarator(variable.Identifier)
                    })));

                    awaitExpr = CSharp.AssignmentExpression(
                        SyntaxKind.SimpleAssignmentExpression,
                        CSharp.IdentifierName(variable.Identifier),
                        (value as AwaitExpressionSyntax)
                        .Expression);
                }
            }

            if (awaitExpr != null)
            {
                var result = VisitExpressionStatement(Templates
                                                      .AwaitExpr
                                                      .Get <ExpressionStatementSyntax>(awaitExpr))
                             as StatementSyntax;

                if (extraStatement != null)
                {
                    var block = Roslyn.TrackNode(CSharp.Block(
                                                     extraStatement,
                                                     result));

                    var document = _scope.GetDocument();
                    document.change(node.Parent, Roslyn.ExplodeBlock(block));
                    return(block);
                }

                return(result);
            }

            return(base.VisitLocalDeclarationStatement(node));
        }
コード例 #2
0
ファイル: ClassLinker.cs プロジェクト: zihotki/Excess
        private StatementSyntax LinkAssignment(AssignmentExpressionSyntax assignment, InvocationExpressionSyntax success, InvocationExpressionSyntax failure, Dictionary <string, TypeSyntax> assignments)
        {
            var leftString = assignment.Left.ToString();
            var leftType   = Roslyn.SymbolTypeSyntax(_model, assignment.Left);

            Debug.Assert(assignment.Left is IdentifierNameSyntax);
            Debug.Assert(!assignments.ContainsKey(leftString));
            Debug.Assert(leftType != null); //td: error

            assignments[leftString] = leftType;

            var emptyAssignments = new Dictionary <string, TypeSyntax>();
            var right            = LinkOperand(assignment.Right, success, failure, emptyAssignments);

            Debug.Assert(right != null);
            Debug.Assert(!emptyAssignments.Any());

            //there are 2 scenarios, first, the right operand was a concurrent expression
            //in which case it would have a success function
            var successFunc = right
                              .DescendantNodes()
                              .OfType <ParenthesizedLambdaExpressionSyntax>()
                              .Where(fn => fn
                                     .ParameterList
                                     .Parameters
                                     .Any(p => p.Identifier.ToString() == "__res"))
                              .SingleOrDefault();

            if (successFunc != null)
            {
                return(right.ReplaceNode(successFunc, successFunc
                                         .WithBody(CSharp.Block(new[] {
                    Templates
                    .ExpressionAssigment
                    .Get <StatementSyntax>(assignment.Left, leftType)
                }
                                                                .Union(successFunc.Body is BlockSyntax
                            ? (successFunc.Body as BlockSyntax)
                                                                       .Statements
                                                                       .AsEnumerable()
                            : new[] { successFunc.Body as StatementSyntax })
                                                                .ToArray()))));
            }

            //else, we need to substitute the actual Right expr by
            //an assignment.
            var rightString = assignment.Right.ToString();

            return(right.ReplaceNodes(right.
                                      DescendantNodes()
                                      .OfType <ExpressionSyntax>()
                                      .Where(node => node.ToString().Equals(rightString)),
                                      (on, nn) => CSharp.AssignmentExpression(
                                          assignment.Kind(),
                                          Templates
                                          .ExpressionProperty
                                          .Get <ExpressionSyntax>(assignment.Left),
                                          nn)));
        }
コード例 #3
0
ファイル: Injection.cs プロジェクト: tylike/Excess
        private static StatementSyntax InjectionAssignment(MemberDeclarationSyntax member)
        {
            var type       = null as TypeSyntax;
            var identifier = MemberIdentifier(member, out type);

            return(CSharp.ExpressionStatement(CSharp.AssignmentExpression(
                                                  SyntaxKind.SimpleAssignmentExpression,
                                                  CSharp.IdentifierName(identifier),
                                                  CSharp.IdentifierName("__" + identifier.ToString()))));
        }
コード例 #4
0
        private static ExpressionSyntax Assignment(ParserRuleContext node)
        {
            if (node.ChildCount == 1)
            {
                return(Expression(node.GetRuleContext <ParserRuleContext>(0)));
            }

            Debug.Assert(node.ChildCount == 3);
            var left  = visitNode(node.GetRuleContext <ParserRuleContext>(0));
            var right = visitNode(node.GetRuleContext <ParserRuleContext>(2));

            SyntaxKind kind;
            var        op = GetBinaryOperator(node.children[1].GetText(), out kind);

            return(CSharp.AssignmentExpression(kind, left, op, right));
        }
コード例 #5
0
ファイル: ExpressionParser.cs プロジェクト: tylike/Excess
        private SyntaxNode Parse(BinaryExpressionSyntax expression, SyntaxToken actor)
        {
            var exprClassName = uniqueId("__expr");

            _operators = new List <Operator>();

            var startStatements = new List <StatementSyntax>();
            var root            = build(expression, null, false, startStatements);

            if (!_operators.Any())
            {
                return(expression);
            }

            var members = new List <MemberDeclarationSyntax>();

            foreach (var op in _operators)
            {
                if (op.Eval != null)
                {
                    members.Add(op.Eval);
                }

                if (op.LeftValue != null)
                {
                    members.Add(op.LeftValue);
                }

                if (op.RightValue != null)
                {
                    members.Add(op.RightValue);
                }

                if (op.StartName != null && op.StartName.Any())
                {
                    members.Add(Templates
                                .OperatorStartField
                                .Get <MemberDeclarationSyntax>(op.StartName, exprClassName));
                }
            }

            var exprClass = Templates
                            .ExpressionClass
                            .Get <ClassDeclarationSyntax>(exprClassName)
                            .WithMembers(CSharp.List(
                                             members));

            _class.AddType(exprClass);

            var startFunc = StartFunction(startStatements, exprClassName, false);

            var result = Templates
                         .ExpressionInstantiation
                         .Get <StatementSyntax>(exprClassName, startFunc, actor);

            return(result.ReplaceNodes(result.DescendantNodes()
                                       .OfType <InitializerExpressionSyntax>(),
                                       (on, nn) => nn
                                       .AddExpressions(_operators
                                                       .Where(op => !string.IsNullOrEmpty(op.StartName))
                                                       .Select(op => (ExpressionSyntax)CSharp.AssignmentExpression(
                                                                   SyntaxKind.SimpleAssignmentExpression,
                                                                   CSharp.IdentifierName(op.StartName),
                                                                   StartFunction(op.Start, exprClassName, true)))
                                                       .ToArray())));
        }
コード例 #6
0
ファイル: ClassLinker.cs プロジェクト: zihotki/Excess
        public override SyntaxNode VisitTryStatement(TryStatementSyntax node)
        {
            _trysInStack++;
            try
            {
                var newNode = (TryStatementSyntax)base.VisitTryStatement(node);

                if (_tryConcurrent)
                {
                    var variableName = "__try" + _trysInStack;
                    _tryVariables.Add(variableName);

                    //we can only split on expressions directly on the try level
                    //i.e. no try { if () { EXPRESSION }}
                    if (_trysInStack > 1 && !(newNode.Parent.Parent is TryStatementSyntax))
                    {
                        Debug.Assert(false); //td: error
                        return(newNode);
                    }

                    var statements    = new List <StatementSyntax>(newNode.Block.Statements);
                    var newStatements = new List <StatementSyntax>();
                    var currentIndex  = 0;

                    while (currentIndex < statements.Count)
                    {
                        var oldIndex = currentIndex;
                        for (int i = oldIndex; i < statements.Count; i++, currentIndex++)
                        {
                            var statement = statements[i];

                            if (statement is YieldStatementSyntax)
                            {
                                newStatements.Add(newNode
                                                  .WithBlock(CSharp.Block(
                                                                 statements
                                                                 .Skip(oldIndex)
                                                                 .Take(currentIndex - oldIndex - 1))));

                                //variable and return yield
                                //td: assert
                                newStatements.Add(statements[currentIndex - 1]);
                                newStatements.Add(statements[currentIndex++]);
                                break;
                            }

                            //must make variables available to later code, unless it precedes a yield
                            var yieldNext = statements.Count > i + 1 && statements[i + 1] is YieldStatementSyntax;
                            if (statement is LocalDeclarationStatementSyntax && !yieldNext)
                            {
                                var decl = statement as LocalDeclarationStatementSyntax;

                                var varType = decl.Declaration.Type;
                                if (varType == null || varType.Kind() == SyntaxKind.TypeVarKeyword)
                                {
                                    varType = Roslyn.SymbolTypeSyntax(_model, decl
                                                                      .Declaration
                                                                      .Variables[0]
                                                                      .Initializer
                                                                      .Value);
                                }

                                Debug.Assert(varType != null, "Untyped local variable on try fix");

                                var assignmentStatements = new List <StatementSyntax>();
                                newStatements.Add(decl
                                                  .WithDeclaration(decl.Declaration
                                                                   .WithType(varType)
                                                                   .WithVariables(CSharp.SeparatedList(
                                                                                      decl
                                                                                      .Declaration
                                                                                      .Variables
                                                                                      .Select(v =>
                                {
                                    assignmentStatements.Add(CSharp.ExpressionStatement(
                                                                 CSharp.AssignmentExpression(
                                                                     SyntaxKind.SimpleAssignmentExpression,
                                                                     CSharp.IdentifierName(v.Identifier),
                                                                     v.Initializer.Value)));

                                    return(v.WithInitializer(v
                                                             .Initializer
                                                             .WithValue(Templates
                                                                        .DefaultValue
                                                                        .Get <ExpressionSyntax>(varType))));
                                })))));

                                //once moved the variables "up" scope
                                //we must keep the assignments
                                Debug.Assert(assignmentStatements.Any());
                                statements.RemoveAt(i);
                                statements.InsertRange(i, assignmentStatements);
                            }
                        }
                    }

                    Debug.Assert(newStatements.Any());
                    return(LinkTryStatements(newStatements, variableName));
                }

                return(newNode);
            }
            finally
            {
                _trysInStack--;
            }
        }