| File: Parser\BlockContexts\SingleLineLambdaContext.vb | Web Access |
| Project: src\roslyn\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic) |
' Licensed to the .NET Foundation under one or more agreements. ' The .NET Foundation licenses this file to you under the MIT license. ' See the LICENSE file in the project root for more information. '----------------------------------------------------------------------------- ' Contains the definition of the BlockContext '----------------------------------------------------------------------------- Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports InternalSyntaxFactory = Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax.SyntaxFactory Namespace Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax Friend NotInheritable Class SingleLineLambdaContext Inherits MethodBlockContext Friend Sub New(statement As StatementSyntax, prevContext As BlockContext) MyBase.New(If(statement.Kind = SyntaxKind.FunctionLambdaHeader, SyntaxKind.SingleLineFunctionLambdaExpression, SyntaxKind.SingleLineSubLambdaExpression), statement, prevContext) Debug.Assert(statement.Kind = SyntaxKind.FunctionLambdaHeader OrElse statement.Kind = SyntaxKind.SubLambdaHeader) Debug.Assert(SyntaxFacts.IsSingleLineLambdaExpression(BlockKind)) End Sub Friend Overrides ReadOnly Property IsLambda As Boolean Get Return True End Get End Property Friend Overrides Function CreateBlockSyntax(endStmt As StatementSyntax) As VisualBasicSyntaxNode Dim statements = Body() Dim statement As VisualBasicSyntaxNode Dim reportRequiresSingleStatement As Boolean If statements.Count = 0 Then statement = InternalSyntaxFactory.EmptyStatement(InternalSyntaxFactory.MissingEmptyToken) reportRequiresSingleStatement = True Else Debug.Assert(statements.Count = 1) statement = DirectCast(statements(0), StatementSyntax) reportRequiresSingleStatement = Not statement.ContainsDiagnostics() AndAlso Not IsSingleStatement(statement) End If ' Single line sub ignores the endStmt which may be nothing or the statement that was just added to the sub. Dim header = DirectCast(BeginStatement, LambdaHeaderSyntax) Dim lambdaExpr = SyntaxFactory.SingleLineLambdaExpression(BlockKind, header, statement) If reportRequiresSingleStatement Then lambdaExpr = Parser.ReportSyntaxError(lambdaExpr, ERRID.ERR_SubRequiresSingleStatement) ElseIf header.Kind = SyntaxKind.FunctionLambdaHeader AndAlso header.Modifiers.Any(SyntaxKind.IteratorKeyword) Then lambdaExpr = Parser.ReportSyntaxError(lambdaExpr, ERRID.ERR_BadIteratorExpressionLambda) End If FreeStatements() Return lambdaExpr End Function Friend Overrides Function EndBlock(endStmt As StatementSyntax) As BlockContext 'Don't create the lambda block and don't pass it to the previous context. The previous context is not the ' right place to store it because the lambda goes into an expression and not the surrounding statement block. Return PrevBlock End Function Friend Overrides Function ResyncAndProcessStatementTerminator(statement As StatementSyntax, lambdaContext As BlockContext) As BlockContext Return ProcessStatementTerminator(lambdaContext) End Function Friend Overrides Function ProcessStatementTerminator(lambdaContext As BlockContext) As BlockContext Dim token = Parser.CurrentToken Select Case token.Kind Case SyntaxKind.StatementTerminatorToken, SyntaxKind.EndOfFileToken ' A single-line lambda is terminated at the end of the line. Case SyntaxKind.ColonToken ' A single-line sub with multiple statements. Report ERR_SubRequiresSingleStatement ' on the first statement and end the sub. If there are no statements, we'll report the ' error, on the entire block, in CreateBlockSyntax instead. If _statements.Count > 0 Then _statements(0) = Parser.ReportSyntaxError(_statements(0), ERRID.ERR_SubRequiresSingleStatement) End If Return EndLambda() End Select Return PrevBlock End Function Friend Overrides ReadOnly Property IsSingleLine As Boolean Get Return True End Get End Property Private Shared Function IsSingleStatement(statement As VisualBasicSyntaxNode) As Boolean Select Case statement.Kind Case SyntaxKind.EmptyStatement, SyntaxKind.MultiLineIfBlock, SyntaxKind.SimpleDoLoopBlock, SyntaxKind.DoWhileLoopBlock, SyntaxKind.DoUntilLoopBlock, SyntaxKind.DoLoopWhileBlock, SyntaxKind.DoLoopUntilBlock, SyntaxKind.ForBlock, SyntaxKind.ForEachBlock, SyntaxKind.SelectBlock, SyntaxKind.WhileBlock, SyntaxKind.WithBlock, SyntaxKind.SyncLockBlock, SyntaxKind.UsingBlock, SyntaxKind.TryBlock Return False Case Else Return True End Select End Function End Class End Namespace