From c121b5b2a69f3f726866c2d089e86aa7246060ec Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Tue, 13 Jun 2017 16:09:32 -0700 Subject: [PATCH] Added tests for unbound lambdas in the operation tree. --- .../CSharpCompilerSemanticTest.csproj | 1 + .../IOperationTests_ILambdaExpression.cs | 116 ++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_ILambdaExpression.cs diff --git a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj index 515394d9c4c..9d966282569 100644 --- a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj +++ b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj @@ -65,6 +65,7 @@ + diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_ILambdaExpression.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_ILambdaExpression.cs new file mode 100644 index 00000000000..660dae82783 --- /dev/null +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_ILambdaExpression.cs @@ -0,0 +1,116 @@ +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.Test.Utilities; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests +{ + internal partial class IOperationTests : SemanticModelTestBase + { + [Fact] + public void ILambdaExpression_BoundLambda_HasValidLambdaExpressionTree() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + Action x /**/= () => F()/**/; + } + + static void F() + { + } +} +"; + string expectedOperationTree = @" +IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'Action x /* ... **/;') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'Action x /* ... **/;') + Variables: Local_1: System.Action x + Initializer: IConversionExpression (ConversionKind.CSharp, Implicit) (OperationKind.ConversionExpression, Type: System.Action) (Syntax: '() => F()') + ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '() => F()') + IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: 'F()') + IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'F()') + IInvocationExpression (static void Program.F()) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'F()') + IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'F()') +"; + var expectedDiagnostics = DiagnosticDescription.None; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [Fact] + public void ILambdaExpression_UnboundLambdaAsVar_HasValidLambdaExpressionTree() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + var x /**/= () => F()/**/; + } + + static void F() + { + } +} +"; + string expectedOperationTree = @" +IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'var x /**/;') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'var x /**/;') + Variables: Local_1: var x + Initializer: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '() => F()') + IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'F()') + IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'F()') + IInvocationExpression (static void Program.F()) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'F()') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS0815: Cannot assign lambda expression to an implicitly-typed variable + // var x /**/= () => F()/**/; + Diagnostic(ErrorCode.ERR_ImplicitlyTypedVariableAssignedBadValue, "x /**/= () => F()").WithArguments("lambda expression").WithLocation(8, 13), + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + + [Fact] + public void ILambdaExpression_UnboundLambdaAsDelegate_HasValidLambdaExpressionTree() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + Action x /**/= () => F()/**/; + } + + static void F() + { + } +} +"; + string expectedOperationTree = @" +IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement, IsInvalid) (Syntax: 'Action ... **/;') + IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration, IsInvalid) (Syntax: 'Action ... **/;') + Variables: Local_1: System.Action x + Initializer: IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: System.Action, IsInvalid) (Syntax: '() => F()') + ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '() => F()') + IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'F()') + IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'F()') + IInvocationExpression (static void Program.F()) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'F()') +"; + var expectedDiagnostics = new DiagnosticDescription[] { + // CS1593: Delegate 'Action' does not take 0 arguments + // Action x /**/= () => F()/**/; + Diagnostic(ErrorCode.ERR_BadDelArgCount, "() => F()").WithArguments("System.Action", "0").WithLocation(8, 35) + }; + + VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); + } + } +} -- GitLab