diff --git a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj index 4a4c65fbab736379eecd1ee2149757e1e2002326..4fda93bf002cf5a1060cf4de589134dca26e4087 100644 --- a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj +++ b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj @@ -60,6 +60,7 @@ + diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_InvalidExpression.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_InvalidExpression.cs new file mode 100644 index 0000000000000000000000000000000000000000..5d91556d6657d71bf727a8f16e736a757809083d --- /dev/null +++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_InvalidExpression.cs @@ -0,0 +1,390 @@ +// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.CSharp.Test.Utilities; +using Microsoft.CodeAnalysis.Test.Utilities; +using Roslyn.Test.Utilities; +using System.Linq; +using Xunit; + +namespace Microsoft.CodeAnalysis.CSharp.UnitTests +{ + public partial class IOperationTests : SemanticModelTestBase + { + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidInvocationExpression_BadReceiver() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + /**/Console.WriteLine2()/**/; + } +} +"; + string expectedOperationTree = @" +IInvocationExpression ( ? ?.()) (OperationKind.InvocationExpression, Type: ?, IsInvalid) + Instance Receiver: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) + IOperation: (OperationKind.None) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidInvocationExpression_OverloadResolutionFailureBadArgument() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + /**/F(string.Empty)/**/; + } + + void F(int x) + { + } +} +"; + string expectedOperationTree = @" +IInvocationExpression ( void Program.F(System.Int32 x)) (OperationKind.InvocationExpression, Type: System.Void, IsInvalid) + Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Program) + IArgument (Matching Parameter: x) (OperationKind.Argument) + IFieldReferenceExpression: System.String System.String.Empty (Static) (OperationKind.FieldReferenceExpression, Type: System.String) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/8813"), WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidInvocationExpression_OverloadResolutionFailureExtraArgument() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + /**/F(string.Empty)/**/; + } + + void F() + { + } +} +"; + string expectedOperationTree = @" +IInvocationExpression ( void Program.F(System.Int32 x)) (OperationKind.InvocationExpression, Type: System.Void, IsInvalid) + Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Program) + IArgument (Matching Parameter: x) (OperationKind.Argument) + IFieldReferenceExpression: System.String System.String.Empty (Static) (OperationKind.FieldReferenceExpression, Type: System.String) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidFieldReferenceExpression() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + var x = new Program(); + var y /**/= x.MissingField/**/; + } + + void F() + { + } +} +"; + string expectedOperationTree = @" +IVariableDeclarationStatement (1 variables) (OperationKind.VariableDeclarationStatement, IsInvalid) + IVariableDeclaration: ? y (OperationKind.VariableDeclaration, IsInvalid) + Initializer: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) + ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: Program) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidConversionExpression_ImplicitCast() + { + string source = @" +using System; + +class Program +{ + int i1; + static void Main(string[] args) + { + var x = new Program(); + string y /**/= x.i1/**/; + } + + void F() + { + } +} +"; + string expectedOperationTree = @" +IVariableDeclarationStatement (1 variables) (OperationKind.VariableDeclarationStatement, IsInvalid) + IVariableDeclaration: System.String y (OperationKind.VariableDeclaration, IsInvalid) + Initializer: IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: System.String, IsInvalid) + IFieldReferenceExpression: System.Int32 Program.i1 (OperationKind.FieldReferenceExpression, Type: System.Int32) + Instance Receiver: ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: Program) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidConversionExpression_ExplicitCast() + { + string source = @" +using System; + +class Program +{ + int i1; + static void Main(string[] args) + { + var x = new Program(); + Program y /**/= (Program)x.i1/**/; + } + + void F() + { + } +} +"; + string expectedOperationTree = @" +IVariableDeclarationStatement (1 variables) (OperationKind.VariableDeclarationStatement, IsInvalid) + IVariableDeclaration: Program y (OperationKind.VariableDeclaration, IsInvalid) + Initializer: IConversionExpression (ConversionKind.Invalid, Explicit) (OperationKind.ConversionExpression, Type: Program, IsInvalid) + IFieldReferenceExpression: System.Int32 Program.i1 (OperationKind.FieldReferenceExpression, Type: System.Int32) + Instance Receiver: ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: Program) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18056"), WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidUnaryExpression() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + var x = new Program(); + Console.Write(/**/++x/**/); + } + + void F() + { + } +} +"; + string expectedOperationTree = @" +IIncrementExpression (UnaryOperandKind.Invalid) (OperationKind.IncrementExpression, Type: System.Object, IsInvalid) + Left: ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: Program) + Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Object, Constant: 1) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidBinaryExpression() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + var x = new Program(); + Console.Write(/**/x + (y * args.Length)/**/); + } + + void F() + { + } +} +"; + string expectedOperationTree = @" +IBinaryOperatorExpression (BinaryOperationKind.Invalid) (OperationKind.BinaryOperatorExpression, Type: ?, IsInvalid) + Left: ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: Program) + Right: IBinaryOperatorExpression (BinaryOperationKind.Invalid) (OperationKind.BinaryOperatorExpression, Type: ?, IsInvalid) + Left: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) + Right: IPropertyReferenceExpression: System.Int32 System.Array.Length { get; } (OperationKind.PropertyReferenceExpression, Type: System.Int32) + Instance Receiver: IParameterReferenceExpression: args (OperationKind.ParameterReferenceExpression, Type: System.String[]) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18057"), WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidLambdaBinding_UnboundLambda() + { + string source = @" +using System; + +class Program +{ + static void Main(string[] args) + { + var x /**/= () => F()/**/; + } + + static void F() + { + } +} +"; + + string expectedLambdaOperationTree = @" +ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) + IBlockStatement (1 statements) (OperationKind.BlockStatement) + IExpressionStatement (OperationKind.ExpressionStatement) + IInvocationExpression (static void Program.F()) (OperationKind.InvocationExpression, Type: System.Void) +"; + VerifyOperationTreeForTest(source, expectedLambdaOperationTree); + + string expectedEqualsValueOperationTree = @" +IVariableDeclarationStatement (1 variables) (OperationKind.VariableDeclarationStatement, IsInvalid) + IVariableDeclaration: var x (OperationKind.VariableDeclaration) + Initializer: IUnboundLambdaExpression (OperationKind.UnboundLambdaExpression, Type: null) + ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) + IBlockStatement (1 statements) (OperationKind.BlockStatement) + IExpressionStatement (OperationKind.ExpressionStatement) + IInvocationExpression (static void Program.F()) (OperationKind.InvocationExpression, Type: System.Void) +"; + VerifyOperationTreeForTest(source, expectedEqualsValueOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidFieldInitializer() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +class Program +{ + int x /**/= Program/**/; + static void Main(string[] args) + { + var x = new Program() { x = Program }; + } +} +"; + string expectedOperationTree = @" +IFieldInitializer (Field: System.Int32 Program.x) (OperationKind.FieldInitializerAtDeclaration, IsInvalid) + IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) + IInvalidExpression (OperationKind.InvalidExpression, Type: Program, IsInvalid) + IOperation: (OperationKind.None) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidArrayInitializer() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +class Program +{ + static void Main(string[] args) + { + var x = new int[2, 2] /**/{ { { 1, 1 } }, { 2, 2 } }/**/; + } +} +"; + string expectedOperationTree = @" +IArrayInitializer (2 elements) (OperationKind.ArrayInitializer, IsInvalid) + IArrayInitializer (1 elements) (OperationKind.ArrayInitializer, IsInvalid) + IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: System.Int32, IsInvalid) + IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) + IArrayInitializer (2 elements) (OperationKind.ArrayInitializer, IsInvalid) + IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object) + ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) + IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object) + ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) + IArrayInitializer (2 elements) (OperationKind.ArrayInitializer) + ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) + ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact, WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidArrayCreation() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +class Program +{ + static void Main(string[] args) + { + var x = /**/new X[Program] { { 1 } }/**/; + } +} +"; + string expectedOperationTree = @" +IArrayCreationExpression (Dimension sizes: 1, Element Type: X) (OperationKind.ArrayCreationExpression, Type: X[], IsInvalid) + IInvalidExpression (OperationKind.InvalidExpression, Type: Program, IsInvalid) + IOperation: (OperationKind.None) + IArrayInitializer (1 elements) (OperationKind.ArrayInitializer, IsInvalid) + IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: X, IsInvalid) + IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) + IArrayInitializer (1 elements) (OperationKind.ArrayInitializer, IsInvalid) + IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object) + ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + + [Fact(Skip = "https://github.com/dotnet/roslyn/issues/18059"), WorkItem(17598, "https://github.com/dotnet/roslyn/issues/17598")] + public void InvalidParameterDefaultValueInitializer() + { + string source = @" +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +class Program +{ + static int M() { return 0; } + void F(int p /**/= M()/**/) + { + } +} +"; + string expectedOperationTree = @" +IParameterInitializer (Parameter: [System.Int32 p = default(System.Int32)]) (OperationKind.ParameterInitializerAtDeclaration, IsInvalid) + IInvocationExpression (static System.Int32 Program.M()) (OperationKind.InvocationExpression, Type: System.Int32, IsInvalid) +"; + VerifyOperationTreeForTest(source, expectedOperationTree); + } + } +} \ No newline at end of file diff --git a/src/Compilers/VisualBasic/Test/Semantic/BasicCompilerSemanticTest.vbproj b/src/Compilers/VisualBasic/Test/Semantic/BasicCompilerSemanticTest.vbproj index 83e2c7f40c5a9b8b1e858130f5a70bcddc408a34..13327536adf30d19b25937cf3c5127522610618d 100644 --- a/src/Compilers/VisualBasic/Test/Semantic/BasicCompilerSemanticTest.vbproj +++ b/src/Compilers/VisualBasic/Test/Semantic/BasicCompilerSemanticTest.vbproj @@ -96,6 +96,7 @@ + diff --git a/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_InvalidExpression.vb b/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_InvalidExpression.vb new file mode 100644 index 0000000000000000000000000000000000000000..e8ff8086e9c5dc0052d73a716f49a32bee7fe8a8 --- /dev/null +++ b/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_InvalidExpression.vb @@ -0,0 +1,328 @@ +' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +Imports Microsoft.CodeAnalysis.Semantics +Imports Microsoft.CodeAnalysis.Test.Utilities +Imports Microsoft.CodeAnalysis.VisualBasic.Syntax +Imports Roslyn.Test.Utilities + +Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics + + Partial Public Class IOperationTests + Inherits SemanticModelTestBase + + + Public Sub InvalidInvocationExpression_BadReceiver() + Dim source = .Value + + ' This might change with https://github.com/dotnet/roslyn/issues/18069 + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of InvocationExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidInvocationExpression_OverloadResolutionFailureBadArgument() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of InvocationExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidInvocationExpression_OverloadResolutionFailureExtraArgument() + Dim source = .Value + + ' This might change with https://github.com/dotnet/roslyn/issues/18069 + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of InvocationExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidFieldReferenceExpression() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of MemberAccessExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidConversionExpression_ImplicitCast() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of MemberAccessExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidConversionExpression_ExplicitCast() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of DirectCastExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidUnaryExpression() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of UnaryExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidBinaryExpression() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of BinaryExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidLambdaBinding_UnboundLambda() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of SingleLineLambdaExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidFieldInitializer() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of EqualsValueSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidArrayInitializer() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of CollectionInitializerSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidArrayCreation() + Dim source = .Value + + ' The operation tree might get affected with https://github.com/dotnet/roslyn/issues/18074 + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of ArrayCreationExpressionSyntax)(source, expectedOperationTree) + End Sub + + + Public Sub InvalidParameterDefaultValueInitializer() + Dim source = .Value + + Dim expectedOperationTree = .Value + + VerifyOperationTreeForTest(Of EqualsValueSyntax)(source, expectedOperationTree) + End Sub + End Class +End Namespace diff --git a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs index dbdacbf4e69d24b4691807e800df2f405e71c556..40e793df7aadc75ddb1aaf35b179ad1feaecc1f8 100644 --- a/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs +++ b/src/Test/Utilities/Portable/Compilation/OperationTreeVerifier.cs @@ -675,7 +675,6 @@ public override void VisitIndexedPropertyReferenceExpression(IIndexedPropertyRef LogString(nameof(IIndexedPropertyReferenceExpression)); LogString($": {operation.Property.ToTestDisplayString()}"); - LogCommonPropertiesAndNewLine(operation); VisitMemberReferenceExpressionCommon(operation); } @@ -905,6 +904,7 @@ public override void VisitArrayCreationExpression(IArrayCreationExpression opera public override void VisitArrayInitializer(IArrayInitializer operation) { LogString(nameof(IArrayInitializer)); + LogString($" ({operation.ElementValues.Length} elements)"); LogCommonPropertiesAndNewLine(operation); base.VisitArrayInitializer(operation);