// 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))); }
// 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))); }
// 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))); } }