Skip to content

Commit

Permalink
remove unnecessary block from bound node for single line lambda (#22571)
Browse files Browse the repository at this point in the history
  • Loading branch information
heejaechang authored Oct 13, 2017
1 parent ac8579e commit 9a09a70
Show file tree
Hide file tree
Showing 3 changed files with 337 additions and 233 deletions.
10 changes: 2 additions & 8 deletions src/Compilers/VisualBasic/Portable/Binding/Binder_Lambda.vb
Original file line number Diff line number Diff line change
Expand Up @@ -478,28 +478,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim singleLineLambdaSyntax = DirectCast(lambdaSyntax, SingleLineLambdaExpressionSyntax)
Dim statement = DirectCast(singleLineLambdaSyntax.Body, StatementSyntax)

Dim boundStatement As BoundStatement

If statement.Kind = SyntaxKind.LocalDeclarationStatement Then
' A local declaration is not allowed in a single line lambda as the top level statement. Report the error here because it is legal
' to have a single line if which contains a local declaration. If the error reporting is done in BindStatement then all local
' declarations are prohibited.

' Bind local declaration, discard diagnostics
Dim ignoredDiagnostics = DiagnosticBag.GetInstance()
boundStatement = bodyBinder.BindBlock(lambdaSyntax, singleLineLambdaSyntax.Statements, ignoredDiagnostics).MakeCompilerGenerated()
block = bodyBinder.BindBlock(lambdaSyntax, singleLineLambdaSyntax.Statements, ignoredDiagnostics).MakeCompilerGenerated()
ignoredDiagnostics.Free()

' Generate a diagnostic and a bad statement node
ReportDiagnostic(diagnostics, statement, ERRID.ERR_SubDisallowsStatement)
boundStatement = New BoundBadStatement(statement, ImmutableArray.Create(Of BoundNode)(boundStatement), hasErrors:=True)
Else
boundStatement = bodyBinder.BindBlock(lambdaSyntax, singleLineLambdaSyntax.Statements, diagnostics).MakeCompilerGenerated()
block = bodyBinder.BindBlock(lambdaSyntax, singleLineLambdaSyntax.Statements, diagnostics).MakeCompilerGenerated()
End If

block = New BoundBlock(lambdaSyntax, Nothing, ImmutableArray(Of LocalSymbol).Empty,
ImmutableArray.Create(boundStatement), boundStatement.HasErrors).MakeCompilerGenerated()

Case SyntaxKind.MultiLineFunctionLambdaExpression,
SyntaxKind.MultiLineSubLambdaExpression

Expand Down
137 changes: 137 additions & 0 deletions src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests.vb
Original file line number Diff line number Diff line change
Expand Up @@ -701,5 +701,142 @@ ICatchClause (Exception type: System.Exception) (OperationKind.CatchClause) (Syn

VerifyOperationTreeAndDiagnosticsForTest(Of CatchBlockSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub

<CompilerTrait(CompilerFeature.IOperation)>
<Fact()>
Public Sub TestSubSingleLineLambda()
Dim source = <![CDATA[
Imports System

Class Test
Sub Method()
Dim a As Action = Sub() Console.Write("hello")'BIND:"Sub() Console.Write("hello")"
End Sub
End Class]]>.Value

Dim expectedOperationTree = <![CDATA[
IAnonymousFunctionExpression (Symbol: Sub ()) (OperationKind.AnonymousFunctionExpression, Type: null) (Syntax: 'Sub() Conso ... te("hello")')
IBlockStatement (3 statements) (OperationKind.BlockStatement, IsImplicit) (Syntax: 'Sub() Conso ... te("hello")')
IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'Console.Write("hello")')
Expression:
IInvocationExpression (Sub System.Console.Write(value As System.String)) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'Console.Write("hello")')
Instance Receiver:
null
Arguments(1):
IArgument (ArgumentKind.Explicit, Matching Parameter: value) (OperationKind.Argument) (Syntax: '"hello"')
ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "hello") (Syntax: '"hello"')
InConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
OutConversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null)
ILabeledStatement (Label: exit) (OperationKind.LabeledStatement, IsImplicit) (Syntax: 'Sub() Conso ... te("hello")')
Statement:
null
IReturnStatement (OperationKind.ReturnStatement, IsImplicit) (Syntax: 'Sub() Conso ... te("hello")')
ReturnedValue:
null
]]>.Value

Dim expectedDiagnostics = String.Empty

VerifyOperationTreeAndDiagnosticsForTest(Of SingleLineLambdaExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub

<CompilerTrait(CompilerFeature.IOperation)>
<Fact()>
Public Sub TestFunctionSingleLineLambda()
Dim source = <![CDATA[
Imports System

Class Test
Sub Method()
Dim a As Func(Of Integer) = Function() 1'BIND:"Function() 1"
End Sub
End Class]]>.Value

Dim expectedOperationTree = <![CDATA[
IAnonymousFunctionExpression (Symbol: Function () As System.Int32) (OperationKind.AnonymousFunctionExpression, Type: null) (Syntax: 'Function() 1')
IBlockStatement (3 statements, 1 locals) (OperationKind.BlockStatement, IsImplicit) (Syntax: 'Function() 1')
Locals: Local_1: <anonymous local> As System.Int32
IReturnStatement (OperationKind.ReturnStatement, IsImplicit) (Syntax: '1')
ReturnedValue:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
ILabeledStatement (Label: exit) (OperationKind.LabeledStatement, IsImplicit) (Syntax: 'Function() 1')
Statement:
null
IReturnStatement (OperationKind.ReturnStatement, IsImplicit) (Syntax: 'Function() 1')
ReturnedValue:
ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.Int32, IsImplicit) (Syntax: 'Function() 1')
]]>.Value

Dim expectedDiagnostics = String.Empty

VerifyOperationTreeAndDiagnosticsForTest(Of SingleLineLambdaExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub

<CompilerTrait(CompilerFeature.IOperation)>
<Fact()>
Public Sub TestFunctionMultiLineLambda()
Dim source = <![CDATA[
Imports System

Class Test
Sub Method()
Dim a As Func(Of Integer) = Function()'BIND:"Function()"
Return 1
End Function
End Sub
End Class]]>.Value

Dim expectedOperationTree = <![CDATA[
IAnonymousFunctionExpression (Symbol: Function () As System.Int32) (OperationKind.AnonymousFunctionExpression, Type: null) (Syntax: 'Function()' ... nd Function')
IBlockStatement (3 statements, 1 locals) (OperationKind.BlockStatement, IsImplicit) (Syntax: 'Function()' ... nd Function')
Locals: Local_1: <anonymous local> As System.Int32
IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'Return 1')
ReturnedValue:
ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1')
ILabeledStatement (Label: exit) (OperationKind.LabeledStatement) (Syntax: 'End Function')
Statement:
null
IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Function')
ReturnedValue:
ILocalReferenceExpression: (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'End Function')
]]>.Value

Dim expectedDiagnostics = String.Empty

VerifyOperationTreeAndDiagnosticsForTest(Of MultiLineLambdaExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub

<CompilerTrait(CompilerFeature.IOperation)>
<Fact()>
Public Sub TestSubMultiLineLambda()
Dim source = <![CDATA[
Imports System

Class Test
Sub Method()
Dim a As Action = Sub()'BIND:"Sub()"
Return
End Sub
End Sub
End Class]]>.Value

Dim expectedOperationTree = <![CDATA[
IAnonymousFunctionExpression (Symbol: Sub ()) (OperationKind.AnonymousFunctionExpression, Type: null) (Syntax: 'Sub()'BIND: ... End Sub')
IBlockStatement (3 statements) (OperationKind.BlockStatement, IsImplicit) (Syntax: 'Sub()'BIND: ... End Sub')
IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'Return')
ReturnedValue:
null
ILabeledStatement (Label: exit) (OperationKind.LabeledStatement) (Syntax: 'End Sub')
Statement:
null
IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'End Sub')
ReturnedValue:
null
]]>.Value

Dim expectedDiagnostics = String.Empty

VerifyOperationTreeAndDiagnosticsForTest(Of MultiLineLambdaExpressionSyntax)(source, expectedOperationTree, expectedDiagnostics)
End Sub
End Class
End Namespace
Loading

0 comments on commit 9a09a70

Please sign in to comment.