Пример #1
0
        public virtual void VisitCFGForeachMoveNextEdge(ForeachMoveNextEdge x)
        {
            Accept(x.ValueVariable);
            Accept(x.KeyVariable);

            x.BodyBlock.Accept(this);
            x.NextBlock.Accept(this);
        }
Пример #2
0
 public override object VisitCFGForeachMoveNextEdge(ForeachMoveNextEdge x)
 {
     return(x.Update(
                (BoundBlock)Accept(x.BodyBlock),
                (BoundBlock)Accept(x.NextBlock),
                x.EnumereeEdge,                              // It updates this reference in its visit instead
                (BoundReferenceExpression)Accept(x.KeyVariable),
                (BoundReferenceExpression)Accept(x.ValueVariable),
                x.MoveSpan));
 }
Пример #3
0
        public override void VisitForeachStmt(ForeachStmt x)
        {
            // binds enumeree expression & connect pre-enumeree-expr blocks
            var boundEnumereeBag = _binder.BindWholeExpression(x.Enumeree, BoundAccess.Read);

            ConnectBoundItemsBagBlocksToCurrentBlock(boundEnumereeBag);

            var end  = NewBlock();
            var move = NewBlock();
            var body = NewBlock();

            // _current -> move -> body -> move -> ...

            // ForeachEnumereeEdge : SimpleEdge
            // x.Enumeree.GetEnumerator();
            var enumereeEdge = new ForeachEnumereeEdge(_current, move, boundEnumereeBag.BoundElement, x.ValueVariable.Alias);

            // ContinueTarget:
            OpenBreakScope(end, move);

            // bind reference expression for foreach key variable
            BoundReferenceExpression keyVar = (x.KeyVariable != null) ?
                                              (BoundReferenceExpression)_binder.BindWholeExpression(x.KeyVariable.Variable, BoundAccess.Write).GetOnlyBoundElement()
                : null;


            // bind reference expression for foreach value variable
            var valueVar = (BoundReferenceExpression)(_binder.BindWholeExpression(
                                                          (Expression)x.ValueVariable.Variable ?? x.ValueVariable.List,
                                                          x.ValueVariable.Alias ? BoundAccess.Write.WithWriteRef(FlowAnalysis.TypeRefMask.AnyType) : BoundAccess.Write
                                                          ).GetOnlyBoundElement());

            // ForeachMoveNextEdge : ConditionalEdge
            var moveEdge = new ForeachMoveNextEdge(move, body, end, enumereeEdge,
                                                   keyVar, valueVar,
                                                   Span.FromBounds(x.Enumeree.Span.End + 1, (x.KeyVariable ?? x.ValueVariable).Span.Start - 1).ToTextSpan() /*"as" between enumeree and variables*/);

            // while (enumerator.MoveNext()) {
            //   var value = enumerator.Current.Value
            //   var key = enumerator.Current.Key

            // Block
            //   { x.Body }
            _current = WithOpenScope(WithNewOrdinal(body));
            VisitElement(x.Body);
            CloseScope();
            //   goto ContinueTarget;
            Connect(_current, move);

            // BreakTarget:
            CloseBreakScope();

            //
            _current = WithNewOrdinal(end);
        }
Пример #4
0
        public override void VisitForeachStmt(ForeachStmt x)
        {
            var end  = NewBlock();
            var move = NewBlock();
            var body = NewBlock();

            // _current -> move -> body -> move -> ...

            // ForeachEnumereeEdge : SimpleEdge
            // x.Enumeree.GetEnumerator();
            var enumereeEdge = new ForeachEnumereeEdge(_current, move, _binder.BindExpression(x.Enumeree, BoundAccess.Read), x.ValueVariable.Alias);

            // ContinueTarget:
            OpenBreakScope(end, move);

            // ForeachMoveNextEdge : ConditionalEdge
            var moveEdge = new ForeachMoveNextEdge(move, body, end, enumereeEdge,
                                                   (x.KeyVariable != null) ? (BoundReferenceExpression)_binder.BindExpression(x.KeyVariable.Variable, BoundAccess.Write) : null,
                                                   (BoundReferenceExpression)_binder.BindExpression(
                                                       (Expression)x.ValueVariable.Variable ?? x.ValueVariable.List,
                                                       x.ValueVariable.Alias ? BoundAccess.Write.WithWriteRef(FlowAnalysis.TypeRefMask.AnyType) : BoundAccess.Write));

            // while (enumerator.MoveNext()) {
            //   var key = enumerator.Current.Key
            //   var value = enumerator.Current.Value

            // Block
            //   { x.Body }
            _current = WithOpenScope(WithNewOrdinal(body));
            VisitElement(x.Body);
            CloseScope();
            //   goto ContinueTarget;
            Connect(_current, move);

            // BreakTarget:
            CloseBreakScope();

            //
            _current = WithNewOrdinal(end);
        }
Пример #5
0
        public override void VisitCFGForeachMoveNextEdge(ForeachMoveNextEdge x)
        {
            var state = _state;
            // get type information from Enumeree to determine types value variable
            var elementType = HandleTraversableUse(x.EnumereeEdge.Enumeree);
            if (elementType.IsVoid) elementType = TypeRefMask.AnyType;

            // Body branch
            _state = state.Clone();
            // set key variable and value variable at current state

            var valueVar = x.ValueVariable;
            if (valueVar is BoundListEx)
            {
                throw new NotImplementedException();
                //VisitListEx(valueVar.List, elementType);
            }
            else
            {
                valueVar.Access = valueVar.Access.WithWrite(elementType);
                Accept(valueVar);

                //
                var keyVar = x.KeyVariable;
                if (keyVar != null)
                {
                    keyVar.Access = keyVar.Access.WithWrite(TypeRefMask.AnyType);
                    Accept(keyVar);
                }
            }
            TraverseToBlock(_state, x.BodyBlock);

            // End branch
            _state = state.Clone();
            TraverseToBlock(_state, x.NextBlock);
        }
Пример #6
0
        public virtual void VisitCFGForeachMoveNextEdge(ForeachMoveNextEdge x)
        {
            Accept(x.ValueVariable);
            Accept(x.KeyVariable);

            x.BodyBlock.Accept(this);
            x.NextBlock.Accept(this);
        }
Пример #7
0
 public virtual TResult VisitCFGForeachMoveNextEdge(ForeachMoveNextEdge x) => DefaultVisitEdge(x);