diff --git a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj
index 4a4c65fbab736379eecd1ee2149757e1e2002326..919da6cb6560607f779c357d5794b483147fa4ac 100644
--- a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj
+++ b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj
@@ -59,6 +59,7 @@
+
diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIfStatement.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIfStatement.cs
new file mode 100644
index 0000000000000000000000000000000000000000..87d5e395e19ffeb9de211532e6b8a8ca4226ccf3
--- /dev/null
+++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIfStatement.cs
@@ -0,0 +1,739 @@
+// 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 Roslyn.Test.Utilities;
+using Xunit;
+
+namespace Microsoft.CodeAnalysis.CSharp.UnitTests
+{
+ public partial class IOperationTests : SemanticModelTestBase
+ {
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementSimpleIf()
+ {
+ string source = @"
+class P
+{
+ private void M()
+ {
+ bool condition=false;
+ /**/if (true)
+ {
+ condition = true;
+ }/**/
+ }
+}
+";
+
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: condition (OperationKind.LocalReferenceExpression, Type: System.Boolean)
+ Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementSimpleIfWithElse()
+ {
+ string source = @"
+class P
+{
+ private void M()
+ {
+ bool condition=false;
+ /**/if (true)
+ {
+ condition = true;
+ }
+ else
+ {
+ condition = false;
+ }/**/
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: condition (OperationKind.LocalReferenceExpression, Type: System.Boolean)
+ Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: condition (OperationKind.LocalReferenceExpression, Type: System.Boolean)
+ Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: False)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementSimpleIfWithConditionEvaluationTrue()
+ {
+ string source = @"
+class P
+{
+ private void M()
+ {
+ bool condition=false;
+ /**/if (1==1)
+ {
+ condition = true;
+ }/**/
+
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean, Constant: True)
+ Left: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1)
+ Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: condition (OperationKind.LocalReferenceExpression, Type: System.Boolean)
+ Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementSimpleIfNested1()
+ {
+ string source = @"
+using System;
+class P
+{
+ private void M()
+ {
+ int m = 12;
+ int n = 18;
+ /**/
+ if (m > 10)
+ {
+ if (n > 20)
+ Console.WriteLine(""Result1"");
+ }
+ else
+ {
+ Console.WriteLine(""Result2"");
+ }/**/
+
+ }
+}
+";
+ var compilation = CreateCompilationWithMscorlib(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular);
+
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: m (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: n (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 20) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 20)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Result1)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Result2)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementSimpleIfNested2()
+ {
+ string source = @"
+using System;
+class P
+{
+private void M()
+ {
+ int m = 9;
+ int n = 7;
+ /**/if (m > 10)
+ if (n > 20)
+ {
+ Console.WriteLine(""Result1"");
+ }
+ else
+ {
+ Console.WriteLine(""Result2"");
+ }/**/
+
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: m (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10)
+ IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: n (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 20) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 20)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Result1)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Result2)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithMultipleCondition()
+ {
+ string source = @"
+using System;
+class P
+{
+ private void M()
+ {
+ int m = 9;
+ int n = 7;
+ int p = 5;
+ /**/if (m >= n && m >= p)
+ {
+ Console.WriteLine(""Nothing is larger than m."");
+ }/**/
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.BooleanConditionalAnd) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: m (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILocalReferenceExpression: n (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: m (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILocalReferenceExpression: p (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Nothing is larger than m.)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithElseIfCondition()
+ {
+ string source = @"
+using System;
+class P
+{
+ private void M()
+ {
+ int m = 9;
+ int n = 7;
+ /**/if (n > 20)
+ {
+ Console.WriteLine(""Result1"");
+ }
+ else if(m > 10)
+ {
+ Console.WriteLine(""Result2"");
+ }
+ else
+ {
+ Console.WriteLine(""Result3"");
+ }/**/
+
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: n (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 20) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 20)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Result1)
+ IIfStatement (OperationKind.IfStatement)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: m (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Result2)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: Result3)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithElseIfConditionOutVar()
+ {
+ string source = @"
+class P
+{
+ private void M()
+ {
+ var s = """";
+ /**/if (int.TryParse(s, out var i))
+ System.Console.WriteLine($""i ={ i}, s ={ s}"");
+ else
+ System.Console.WriteLine($""i ={ i}, s ={ s}"");/**/
+
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IInvocationExpression (static System.Boolean System.Int32.TryParse(System.String s, out System.Int32 result)) (OperationKind.InvocationExpression, Type: System.Boolean)
+ IArgument (Matching Parameter: s) (OperationKind.Argument)
+ ILocalReferenceExpression: s (OperationKind.LocalReferenceExpression, Type: System.String)
+ IArgument (Matching Parameter: result) (OperationKind.Argument)
+ ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ IOperation: (OperationKind.None)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ IOperation: (OperationKind.None)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithOutVar()
+ {
+ string source = @"
+class P
+{
+ private void M()
+ {
+
+ /**/if (true)
+ System.Console.WriteLine(A());/**/
+ }
+ private int A()
+ {
+ var s = """";
+ if (int.TryParse(s, out var i))
+ {
+ return i;
+ }
+ else
+ {
+ return -1;
+ }
+
+ }
+
+}
+
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.Int32 value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ IInvocationExpression ( System.Int32 P.A()) (OperationKind.InvocationExpression, Type: System.Int32)
+ Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: P)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementExplictEmbeddedOutVar()
+ {
+ string source = @"
+class P
+{
+ private void M()
+ {
+ var s = ""data"";
+ /**/if (true)
+ {
+ A(int.TryParse(s, out var i));
+ }/**/
+ }
+ private void A(bool flag)
+ {
+ if (flag)
+ {
+ System.Console.WriteLine(""Result1"");
+ }
+ }
+
+}
+
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement)
+ Local_1: System.Int32 i
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression ( void P.A(System.Boolean flag)) (OperationKind.InvocationExpression, Type: System.Void)
+ Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: P)
+ IArgument (Matching Parameter: flag) (OperationKind.Argument)
+ IInvocationExpression (static System.Boolean System.Int32.TryParse(System.String s, out System.Int32 result)) (OperationKind.InvocationExpression, Type: System.Boolean)
+ IArgument (Matching Parameter: s) (OperationKind.Argument)
+ ILocalReferenceExpression: s (OperationKind.LocalReferenceExpression, Type: System.String)
+ IArgument (Matching Parameter: result) (OperationKind.Argument)
+ ILocalReferenceExpression: i (OperationKind.LocalReferenceExpression, Type: System.Int32)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementImplicitEmbeddedOutVar()
+ {
+ string source = @"
+class Program
+{
+ static void Main(string[] args)
+ {
+ object o = 25;
+ /**/if (true)
+ A(o is int i, 1);/**/
+ }
+
+ private static void A(bool flag, int number)
+ {
+ if (flag)
+ {
+ System.Console.WriteLine(new string('*', number));
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement)
+ Local_1: System.Int32 i
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void Program.A(System.Boolean flag, System.Int32 number)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: flag) (OperationKind.Argument)
+ IOperation: (OperationKind.None)
+ IArgument (Matching Parameter: number) (OperationKind.Argument)
+ ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithConditionPattern()
+ {
+ string source = @"
+using System;
+
+class P
+{
+ private void M()
+ {
+ object obj = ""pattern"";
+
+ /**/if (obj is string str)
+ {
+ Console.WriteLine(str);
+ }/**/
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IOperation: (OperationKind.None)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILocalReferenceExpression: str (OperationKind.LocalReferenceExpression, Type: System.String)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithPattern()
+ {
+ string source = @"
+class Program
+{
+ static void Main(string[] args)
+ {
+ /**/if (true)
+ A(25);/**/
+ }
+
+ private static void A(object o)
+ {
+ if (o is null) return;
+ if (!(o is int i)) return;
+ System.Console.WriteLine(new string('*', i));
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void Program.A(System.Object o)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: o) (OperationKind.Argument)
+ IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object)
+ ILiteralExpression (Text: 25) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 25)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithEmbeddedPattern()
+ {
+ string source = @"
+class Program
+{
+ static void Main(string[] args)
+ {
+ object o = 25;
+ /**/if (true)
+ {
+ A(o is int i, 1);
+ }/**/
+ }
+
+ private static void A(bool flag, int number)
+ {
+ if (flag)
+ {
+ System.Console.WriteLine(new string('*', number));
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IBlockStatement (1 statements, 1 locals) (OperationKind.BlockStatement)
+ Local_1: System.Int32 i
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void Program.A(System.Boolean flag, System.Int32 number)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: flag) (OperationKind.Argument)
+ IOperation: (OperationKind.None)
+ IArgument (Matching Parameter: number) (OperationKind.Argument)
+ ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithElseMissing()
+ {
+ string source = @"
+using System;
+
+class P
+{
+ private void M()
+ {
+ object obj = ""pattern"";
+
+ /**/if (obj is string str)
+ {
+ Console.WriteLine(str);
+ }
+ else
+/**/ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement, IsInvalid)
+ Condition: IOperation: (OperationKind.None)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression (static void System.Console.WriteLine(System.String value)) (OperationKind.InvocationExpression, Type: System.Void)
+ IArgument (Matching Parameter: value) (OperationKind.Argument)
+ ILocalReferenceExpression: str (OperationKind.LocalReferenceExpression, Type: System.String)
+ IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid)
+ IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithConditionMissing()
+ {
+ string source = @"
+using System;
+
+class P
+{
+ private void M()
+ {
+ int a = 1;
+ /**/if ()
+ {
+ a = 2;
+ }
+ else
+ {
+ a = 3;
+ }/**/
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement, IsInvalid)
+ Condition: IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: System.Boolean, IsInvalid)
+ IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Int32)
+ Left: ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IAssignmentExpression (OperationKind.AssignmentExpression, Type: System.Int32)
+ Left: ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 3) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithStatementMissing()
+ {
+ string source = @"
+using System;
+
+class P
+{
+ private void M()
+ {
+ int a = 1;
+ /**/if (a==1)
+ else
+/**/
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement, IsInvalid)
+ Condition: IBinaryOperatorExpression (BinaryOperationKind.IntegerEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean)
+ Left: ILocalReferenceExpression: a (OperationKind.LocalReferenceExpression, Type: System.Int32)
+ Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1)
+ IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid)
+ IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid)
+ IExpressionStatement (OperationKind.ExpressionStatement, IsInvalid)
+ IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithFuncCall()
+ {
+ string source = @"
+using System;
+
+class P
+{
+ private void M()
+ {
+ /**/if (true)
+ A();
+ else
+ B();/**/
+ }
+ private void A()
+ {
+ Console.WriteLine(""A"");
+ }
+ private void B()
+ {
+ Console.WriteLine(""B"");
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression ( void P.A()) (OperationKind.InvocationExpression, Type: System.Void)
+ Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: P)
+ IExpressionStatement (OperationKind.ExpressionStatement)
+ IInvocationExpression ( void P.B()) (OperationKind.InvocationExpression, Type: System.Void)
+ Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: P)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ [Fact, WorkItem(17601, "https://github.com/dotnet/roslyn/issues/17601")]
+ public void IIfstatementWithDynamic()
+ {
+ string source = @"
+using System;
+
+class C
+{
+ public static int F(dynamic d, Type t, T x) where T : struct
+ {
+ /**/if (d.GetType() == t && ((T)d).Equals(x))
+ {
+ return 1;
+ }/**/
+
+ return 2;
+ }
+}
+";
+ string expectedOperationTree = @"
+IIfStatement (OperationKind.IfStatement)
+ Condition: IUnaryOperatorExpression (UnaryOperationKind.DynamicTrue) (OperationKind.UnaryOperatorExpression, Type: System.Boolean)
+ IBinaryOperatorExpression (BinaryOperationKind.DynamicAnd) (OperationKind.BinaryOperatorExpression, Type: dynamic)
+ Left: IBinaryOperatorExpression (BinaryOperationKind.Invalid) (OperationKind.BinaryOperatorExpression, Type: dynamic)
+ Left: IOperation: (OperationKind.None)
+ Right: IParameterReferenceExpression: t (OperationKind.ParameterReferenceExpression, Type: System.Type)
+ Right: IInvocationExpression (virtual System.Boolean System.ValueType.Equals(System.Object obj)) (OperationKind.InvocationExpression, Type: System.Boolean)
+ Instance Receiver: IConversionExpression (ConversionKind.CSharp, Explicit) (OperationKind.ConversionExpression, Type: T)
+ IParameterReferenceExpression: d (OperationKind.ParameterReferenceExpression, Type: dynamic)
+ IArgument (Matching Parameter: obj) (OperationKind.Argument)
+ IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Object)
+ IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: T)
+ IBlockStatement (1 statements) (OperationKind.BlockStatement)
+ IReturnStatement (OperationKind.ReturnStatement)
+ ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1)
+";
+ VerifyOperationTreeForTest(source, expectedOperationTree);
+ }
+
+ }
+}
diff --git a/src/Compilers/VisualBasic/Test/Semantic/BasicCompilerSemanticTest.vbproj b/src/Compilers/VisualBasic/Test/Semantic/BasicCompilerSemanticTest.vbproj
index 83e2c7f40c5a9b8b1e858130f5a70bcddc408a34..4c4c938c888b5b9fe5756474c156d1f8f2b2b607 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_IIfStatement.vb b/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IIfStatement.vb
new file mode 100644
index 0000000000000000000000000000000000000000..d9505d737bc60827ef54ee7fe4c2408f5f7262db
--- /dev/null
+++ b/src/Compilers/VisualBasic/Test/Semantic/IOperation/IOperationTests_IIfStatement.vb
@@ -0,0 +1,612 @@
+' 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.VisualBasic.Syntax
+Imports Roslyn.Test.Utilities
+
+Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests.Semantics
+
+ Partial Public Class IOperationTests
+ Inherits SemanticModelTestBase
+
+
+ Public Sub IIfstatementSingleLineIf()
+ Dim source = 0 Then returnValue = count'BIND:"If count > 0 Then returnValue = count"
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of SingleLineIfStatementSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementMultiLineIf()
+ Dim source = 0 Then'BIND:"If count > 0 Then"
+ returnValue = count
+ End If
+ End Sub
+ End Module
+
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementSingleLineIfAndElse()
+ Dim source = 10 Then data = data + count Else data = data - count'BIND:"If count > 10 Then data = data + count Else data = data - count"
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of SingleLineIfStatementSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementSingleLineIfAndElseNested()
+ Dim source = 10 Then If n > 20 Then returnValue = n'BIND:"If m > 10 Then If n > 20 Then returnValue = n"
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of SingleLineIfStatementSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementSimpleIfWithConditionEvaluationTrue()
+ Dim source = .Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementSimpleIfWithConditionConstantFalse()
+ Dim source = .Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementSingleLineWithOperator()
+ Dim source = 10 And n > 20) Then returnValue = n'BIND:"If (m > 10 And n > 20) Then returnValue = n"
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of SingleLineIfStatementSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementMultiLineIfWithElse()
+ Dim source = 0 Then'BIND:"If count > 0 Then"
+ returnValue = count
+ Else
+ returnValue = -1
+ End If
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementSimpleIfNested1()
+ Dim source = 10) Then'BIND:"If (m > 10) Then"
+ If (n > 20) Then
+ Console.WriteLine("Result 1")
+ End If
+ Else
+ Console.WriteLine("Result 2")
+ End If
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementIfNested2()
+ Dim source = 10) Then'BIND:"If (m > 10) Then"
+ If (n > 20) Then
+ Console.WriteLine("Result 1")
+ Else
+ Console.WriteLine("Result 2")
+ End If
+ End If
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementWithMultipleCondition()
+ Dim source = = n AndAlso m >= p) Then'BIND:"If (m >= n AndAlso m >= p) Then"
+ Console.WriteLine("Nothing Is larger than m.")
+ End If
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementWithElseIfCondition()
+ Dim source = 20) Then'BIND:"If (m > 20) Then"
+ Console.WriteLine("Result1")
+ ElseIf (n > 10) Then
+ Console.WriteLine("Result2")
+ Else
+ Console.WriteLine("Result3")
+ End If
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementWithElseIfSingleLine()
+ Dim source = 20) Then System.Console.WriteLine("Result1") Else If (n > 10) Then System.Console.WriteLine("Result2") Else System.Console.WriteLine("Result3") End If'BIND:"If (m > 20) Then System.Console.WriteLine("Result1") Else If (n > 10) Then System.Console.WriteLine("Result2") Else System.Console.WriteLine("Result3")"
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of SingleLineIfStatementSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementWithElseMissing()
+ Dim source = 20) Then'BIND:"If (m > 20) Then"
+ Console.WriteLine("Result1")
+ Else
+ End Sub
+End Module
+ ]]>.Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementWithConditionMissing()
+ Dim source = .Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementWithStatementMissing()
+ Dim source = .Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+
+ Public Sub IIfstatementWithFuncCall()
+ Dim source = .Value
+
+ Dim expectedOperationTree = .Value
+
+ VerifyOperationTreeForTest(Of MultiLineIfBlockSyntax)(source, expectedOperationTree)
+ End Sub
+
+ End Class
+End Namespace