Beispiel #1
0
        // insert the implicit "return" statement at the end of the method body
        // Normally, we wouldn't bother attaching syntax trees to compiler-generated nodes, but these
        // ones are going to have sequence points.
        internal static BoundBlock AppendImplicitReturn(BoundStatement node, MethodSymbol method = null, CSharpSyntaxNode syntax = null)
        {
            if (syntax == null)
            {
                syntax = node.Syntax;
            }

            BoundStatement ret =
                (object)method != null && (object)method.IteratorElementType != null
                ? BoundYieldBreakStatement.Synthesized(syntax) as BoundStatement
                : BoundReturnStatement.Synthesized(syntax, null);

            if (syntax.Kind == SyntaxKind.Block)
            {
                var blockSyntax = (BlockSyntax)syntax;

                ret = new BoundSequencePointWithSpan(
                    blockSyntax,
                    ret,
                    blockSyntax.CloseBraceToken.Span)
                {
                    WasCompilerGenerated = true
                };
            }

            switch (node.Kind)
            {
            case BoundKind.Block:
                var block = (BoundBlock)node;
                return(block.Update(block.LocalsOpt, block.Statements.Add(ret)));

            default:
                return(new BoundBlock(syntax, ImmutableArray <LocalSymbol> .Empty, ImmutableArray.Create(ret, node)));
            }
        }
Beispiel #2
0
        // insert the implicit "return" statement at the end of the method body
        // Normally, we wouldn't bother attaching syntax trees to compiler-generated nodes, but these
        // ones are going to have sequence points.
        internal static BoundBlock AppendImplicitReturn(BoundBlock body, MethodSymbol method, CSharpSyntaxNode syntax = null)
        {
            Debug.Assert(body != null);
            Debug.Assert(method != null);

            if (syntax == null)
            {
                syntax = body.Syntax;
            }

            Debug.Assert(body.WasCompilerGenerated || syntax.IsKind(SyntaxKind.Block) || syntax.IsKind(SyntaxKind.ArrowExpressionClause));

            BoundStatement ret = method.IsIterator
                ? (BoundStatement)BoundYieldBreakStatement.Synthesized(syntax)
                : BoundReturnStatement.Synthesized(syntax, null);

            // Implicitly added return for async method does not need sequence points since lowering would add one.
            if (syntax.IsKind(SyntaxKind.Block) && !method.IsAsync)
            {
                var blockSyntax = (BlockSyntax)syntax;

                ret = new BoundSequencePointWithSpan(
                    blockSyntax,
                    ret,
                    blockSyntax.CloseBraceToken.Span)
                {
                    WasCompilerGenerated = true
                };
            }

            return(body.Update(body.Locals, body.Statements.Add(ret)));
        }
Beispiel #3
0
 public override BoundStatement InstrumentYieldBreakStatement(
     BoundYieldBreakStatement original,
     BoundStatement rewritten
     )
 {
     return(Previous.InstrumentYieldBreakStatement(original, rewritten));
 }
Beispiel #4
0
 public virtual BoundStatement InstrumentYieldBreakStatement(
     BoundYieldBreakStatement original,
     BoundStatement rewritten
     )
 {
     Debug.Assert(
         !original.WasCompilerGenerated || original.Syntax.Kind() == SyntaxKind.Block
         );
     return(rewritten);
 }
        public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
        {
            rewritten = base.InstrumentYieldBreakStatement(original, rewritten);

            if (original.WasCompilerGenerated && original.Syntax.Kind() == SyntaxKind.Block)
            {
                // implicit yield break added by the compiler
                return(new BoundSequencePointWithSpan(original.Syntax, rewritten, ((BlockSyntax)original.Syntax).CloseBraceToken.Span));
            }

            return(AddSequencePoint(rewritten));
        }
Beispiel #6
0
        public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
        {
            Debug.Assert(_asyncIteratorInfo != null);

            // Produce:
            //  disposeMode = true;
            //  goto _enclosingFinallyOrExitLabel;

            return(F.Block(
                       // disposeMode = true;
                       SetDisposeMode(true),
                       // goto _enclosingFinallyOrExitLabel;
                       F.Goto(_enclosingFinallyOrExitLabel)));
        }
Beispiel #7
0
        public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
        {
            Debug.Assert(_asyncIteratorInfo != null);

            // Produce:
            //  disposeMode = true;
            //  goto currentDisposalLabel;

            Debug.Assert(_currentDisposalLabel is object); // no yield break allowed inside a finally
            return(F.Block(
                       // disposeMode = true;
                       SetDisposeMode(true),
                       // goto currentDisposalLabel;
                       F.Goto(_currentDisposalLabel)));
        }
Beispiel #8
0
        public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
        {
            var result = (BoundStatement)base.VisitYieldBreakStatement(node);

            // We also add sequence points for the implicit "yield break" statement at the end of the method body
            // (added by FlowAnalysisPass.AppendImplicitReturn). Implicitly added "yield break" for async method
            // does not need sequence points added here since it would be done later (presumably during Async rewrite).
            if (this.Instrument &&
                (!node.WasCompilerGenerated || (node.Syntax.Kind() == SyntaxKind.Block && _factory.CurrentFunction?.IsAsync == false)))
            {
                result = _instrumenter.InstrumentYieldBreakStatement(node, result);
            }

            return(result);
        }
Beispiel #9
0
        public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
        {
            var result = (BoundStatement)base.VisitYieldBreakStatement(node);

            // We also add sequence points for the implicit "yield break" statement at the end of the method body
            // (added by FlowAnalysisPass.AppendImplicitReturn). Implicitly added "yield break" for async method 
            // does not need sequence points added here since it would be done later (presumably during Async rewrite).
            if (this.Instrument && 
                (!node.WasCompilerGenerated || (node.Syntax.Kind() == SyntaxKind.Block && _factory.CurrentMethod?.IsAsync == false)))
            {
                result = _instrumenter.InstrumentYieldBreakStatement(node, result);
            }

            return result;
        }
Beispiel #10
0
        // insert the implicit "return" statement at the end of the method body
        // Normally, we wouldn't bother attaching syntax trees to compiler-generated nodes, but these
        // ones are going to have sequence points.
        internal static BoundBlock AppendImplicitReturn(BoundBlock body, MethodSymbol method)
        {
            Debug.Assert(body != null);
            Debug.Assert(method != null);

            SyntaxNode syntax = body.Syntax;

            Debug.Assert(body.WasCompilerGenerated ||
                         syntax.IsKind(SyntaxKind.Block) ||
                         syntax.IsKind(SyntaxKind.ArrowExpressionClause) ||
                         syntax.IsKind(SyntaxKind.ConstructorDeclaration));

            BoundStatement ret = (method.IsIterator && !method.IsAsync)
                ? (BoundStatement)BoundYieldBreakStatement.Synthesized(syntax)
                : BoundReturnStatement.Synthesized(syntax, RefKind.None, null);

            return(body.Update(body.Locals, body.LocalFunctions, body.Statements.Add(ret)));
        }
Beispiel #11
0
        public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
        {
            Debug.Assert(_asyncIteratorInfo != null);

            // Produce:
            //  _promiseOfValueOrEnd.SetResult(false);
            //  return;

            var blockBuilder = ArrayBuilder <BoundStatement> .GetInstance();


            blockBuilder.Add(
                // _promiseOfValueOrEnd.SetResult(false);
                GenerateSetResultOnPromise(false));

            // return;
            blockBuilder.Add(F.Return());

            return(F.Block(blockBuilder.ToImmutableAndFree()));
        }
Beispiel #12
0
        // insert the implicit "return" statement at the end of the method body
        // Normally, we wouldn't bother attaching syntax trees to compiler-generated nodes, but these
        // ones are going to have sequence points.
        internal static BoundBlock AppendImplicitReturn(BoundStatement node, MethodSymbol method, CSharpSyntaxNode syntax = null)
        {
            Debug.Assert(method != null);

            if (syntax == null)
            {
                syntax = node.Syntax;
            }

            BoundStatement ret = method.IsIterator
                ? (BoundStatement)BoundYieldBreakStatement.Synthesized(syntax)
                : BoundReturnStatement.Synthesized(syntax, null);

            if (syntax.Kind() == SyntaxKind.Block)
            {
                // Implicitly added return for async method does not need sequence points since lowering would add one.
                if (!method.IsAsync)
                {
                    var blockSyntax = (BlockSyntax)syntax;

                    ret = new BoundSequencePointWithSpan(
                        blockSyntax,
                        ret,
                        blockSyntax.CloseBraceToken.Span)
                    {
                        WasCompilerGenerated = true
                    };
                }
            }

            switch (node.Kind)
            {
            case BoundKind.Block:
                var block = (BoundBlock)node;
                return(block.Update(block.Locals, block.Statements.Add(ret)));

            default:
                return(new BoundBlock(syntax, ImmutableArray <LocalSymbol> .Empty, ImmutableArray.Create(ret, node)));
            }
        }
 public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
 {
     return(AddSequencePoint((BoundStatement)base.VisitYieldBreakStatement(node)));
 }
Beispiel #14
0
 public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
 {
     return(AddDynamicAnalysis(original, base.InstrumentYieldBreakStatement(original, rewritten)));
 }
Beispiel #15
0
        public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
        {
            rewritten = base.InstrumentYieldBreakStatement(original, rewritten);

            if (original.WasCompilerGenerated && original.Syntax.Kind() == SyntaxKind.Block)
            {
                // implicit yield break added by the compiler
                return new BoundSequencePointWithSpan(original.Syntax, rewritten, ((BlockSyntax)original.Syntax).CloseBraceToken.Span);
            }

            return AddSequencePoint(rewritten);
        }
 public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
 {
     return GenerateReturn(finished: true);
 }
 public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
 {
     return(GenerateReturn(finished: true));
 }
Beispiel #18
0
 public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
 {
     return Previous.InstrumentYieldBreakStatement(original, rewritten);
 }
Beispiel #19
0
 public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node)
 {
     return AddSequencePoint((BoundStatement)base.VisitYieldBreakStatement(node));
 }
Beispiel #20
0
 public virtual BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
 {
     Debug.Assert(!original.WasCompilerGenerated || original.Syntax.Kind() == SyntaxKind.Block);
     return rewritten;
 }
 public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten)
 {
     return AddDynamicAnalysis(original, base.InstrumentYieldBreakStatement(original, rewritten));
 }