// 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))); } }
// 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))); }
public override BoundStatement InstrumentYieldBreakStatement( BoundYieldBreakStatement original, BoundStatement rewritten ) { return(Previous.InstrumentYieldBreakStatement(original, rewritten)); }
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)); }
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))); }
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))); }
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); }
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; }
// 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))); }
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())); }
// 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))); }
public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten) { return(AddDynamicAnalysis(original, base.InstrumentYieldBreakStatement(original, 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); }
public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node) { return GenerateReturn(finished: true); }
public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node) { return(GenerateReturn(finished: true)); }
public override BoundStatement InstrumentYieldBreakStatement(BoundYieldBreakStatement original, BoundStatement rewritten) { return Previous.InstrumentYieldBreakStatement(original, rewritten); }
public override BoundNode VisitYieldBreakStatement(BoundYieldBreakStatement node) { return AddSequencePoint((BoundStatement)base.VisitYieldBreakStatement(node)); }
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)); }