diff --git a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj
index 94f456d018d05c83ddbeaa455c5922a337d9466f..ee7993d83d3bd0fc301892c731b745fdb864a4ce 100644
--- a/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj
+++ b/src/Compilers/CSharp/Test/Semantic/CSharpCompilerSemanticTest.csproj
@@ -38,4 +38,4 @@
-
\ No newline at end of file
+
diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IDynamicMemberReferenceExpression.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IDynamicMemberReferenceExpression.cs
new file mode 100644
index 0000000000000000000000000000000000000000..97613383a8f8557720822e7ded4f40165e1c7a65
--- /dev/null
+++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IDynamicMemberReferenceExpression.cs
@@ -0,0 +1,372 @@
+using Microsoft.CodeAnalysis.CSharp.Syntax;
+using Microsoft.CodeAnalysis.Test.Utilities;
+using Xunit;
+
+namespace Microsoft.CodeAnalysis.CSharp.UnitTests
+{
+ public partial class IOperationTests : SemanticModelTestBase
+ {
+ [Fact]
+ public void IDynamicMemberReferenceExpression_SimplePropertyAccess()
+ {
+ string source = @"
+using System;
+
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ int i = /**/d.Prop1/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IDynamicMemberReferenceExpression (Member name: Prop1, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.Prop1')
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = DiagnosticDescription.None;
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_InvalidPropertyAccess()
+ {
+ string source = @"
+using System;
+
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ int i = /**/d./**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IDynamicMemberReferenceExpression (Member name: , Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic, IsInvalid) (Syntax: 'd./**/')
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = new DiagnosticDescription[] {
+ // CS1001: Identifier expected
+ // int i = /**/d./**/;
+ Diagnostic(ErrorCode.ERR_IdentifierExpected, ";").WithLocation(11, 44)
+ };
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_SimpleMethodCall()
+ {
+ string source = @"
+using System;
+
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.GetValue()/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IOperation: (OperationKind.None) (Syntax: 'd.GetValue()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: GetValue, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.GetValue')
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = DiagnosticDescription.None;
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_InvalidMethodCall_MissingName()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.()/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: , Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic, IsInvalid) (Syntax: 'd.')
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = new DiagnosticDescription[] {
+ // CS1001: Identifier expected
+ // /**/d.()/**/;
+ Diagnostic(ErrorCode.ERR_IdentifierExpected, "(").WithLocation(9, 25)
+ };
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_InvalidMethodCall_MissingCloseParen()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.GetValue(/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.GetValue(/**/')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: GetValue, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.GetValue')
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = new DiagnosticDescription[] {
+ // CS1026: ) expected
+ // /**/d.GetValue(/**/;
+ Diagnostic(ErrorCode.ERR_CloseParenExpected, ";").WithLocation(9, 45)
+ };
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReference_GenericMethodCall_SingleGeneric()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.GetValue()/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IOperation: (OperationKind.None) (Syntax: 'd.GetValue()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: GetValue, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.GetValue')
+ Type Arguments: System.Int32
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = DiagnosticDescription.None;
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReference_GenericMethodCall_MultipleGeneric()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.GetValue()/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IOperation: (OperationKind.None) (Syntax: 'd.GetValue()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: GetValue, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.GetValue')
+ Type Arguments:
+ System.Int32
+ ConsoleApp1.C1
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = DiagnosticDescription.None;
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_GenericPropertyAccess()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.GetValue/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IDynamicMemberReferenceExpression (Member name: GetValue, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic, IsInvalid) (Syntax: 'd.GetValue')
+ Type Arguments:
+ System.Int32
+ ConsoleApp1.C1
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic, IsInvalid) (Syntax: 'd')
+";
+ var expectedDiagnostics = new DiagnosticDescription[] {
+ // CS0307: The property 'GetValue' cannot be used with type arguments
+ // /**/d.GetValue/**/;
+ Diagnostic(ErrorCode.ERR_TypeArgsNotAllowed, "GetValue").WithArguments("GetValue", "property").WithLocation(9, 25),
+ // CS0201: Only assignment, call, increment, decrement, and new object expressions can be used as a statement
+ // /**/d.GetValue/**/;
+ Diagnostic(ErrorCode.ERR_IllegalStatement, "d.GetValue").WithLocation(9, 23)
+ };
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_GenericMethodCall_InvalidGenericParam()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.GetValue()/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IOperation: (OperationKind.None, IsInvalid) (Syntax: 'd.GetValue()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: GetValue, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic, IsInvalid) (Syntax: 'd.GetValue')
+ Type Arguments:
+ System.Int32
+ ?
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = new DiagnosticDescription[] {
+ // CS1031: Type expected
+ // /**/d.GetValue()/**/;
+ Diagnostic(ErrorCode.ERR_TypeExpected, ">").WithLocation(9, 38)
+ };
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_NestedDynamicPropertyAccess()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ object o = /**/d.Prop1.Prop2/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IDynamicMemberReferenceExpression (Member name: Prop2, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.Prop1.Prop2')
+ Instance Receiver: IDynamicMemberReferenceExpression (Member name: Prop1, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.Prop1')
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = DiagnosticDescription.None;
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_NestedDynamicMethodAccess()
+ {
+ string source = @"
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ /**/d.Method1().Method2()/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IOperation: (OperationKind.None) (Syntax: 'd.Method1().Method2()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: Method2, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.Method1().Method2')
+ Instance Receiver: IOperation: (OperationKind.None) (Syntax: 'd.Method1()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: Method1, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.Method1')
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = DiagnosticDescription.None;
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+
+ [Fact]
+ public void IDynamicMemberReferenceExpression_NestedDynamicPropertyAndMethodAccess()
+ {
+ string source = @"
+using System;
+
+namespace ConsoleApp1
+{
+ class C1
+ {
+ static void M1()
+ {
+ dynamic d = null;
+ int i = /**/d.Method1().Prop2/**/;
+ }
+ }
+}
+";
+ string expectedOperationTree = @"
+IDynamicMemberReferenceExpression (Member name: Prop2, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.Method1().Prop2')
+ Instance Receiver: IOperation: (OperationKind.None) (Syntax: 'd.Method1()')
+ Children(1):
+ IDynamicMemberReferenceExpression (Member name: Method1, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.Method1')
+ Type Arguments: System.Int32
+ Instance Receiver: ILocalReferenceExpression: d (OperationKind.LocalReferenceExpression, Type: dynamic) (Syntax: 'd')
+";
+ var expectedDiagnostics = DiagnosticDescription.None;
+
+ VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics);
+ }
+ }
+}
diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIfStatement.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIfStatement.cs
index bed4ed6eae1ef9614a76409be2c6e74f14ff7ff8..9ac0918d11cf16b0d905fd9773ce3659c2b0f41f 100644
--- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIfStatement.cs
+++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IIfStatement.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+// 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;
@@ -931,9 +931,8 @@ class C
Left: IBinaryOperatorExpression (BinaryOperationKind.Invalid) (OperationKind.BinaryOperatorExpression, Type: dynamic) (Syntax: 'd.GetType() == t')
Left: IOperation: (OperationKind.None) (Syntax: 'd.GetType()')
Children(1):
- IOperation: (OperationKind.None) (Syntax: 'd.GetType')
- Children(1):
- IParameterReferenceExpression: d (OperationKind.ParameterReferenceExpression, Type: dynamic) (Syntax: 'd')
+ IDynamicMemberReferenceExpression (Member name: GetType, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'd.GetType')
+ Instance Receiver: IParameterReferenceExpression: d (OperationKind.ParameterReferenceExpression, Type: dynamic) (Syntax: 'd')
Right: IParameterReferenceExpression: t (OperationKind.ParameterReferenceExpression, Type: System.Type) (Syntax: 't')
Right: IInvocationExpression (virtual System.Boolean System.ValueType.Equals(System.Object obj)) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: '((T)d).Equals(x)')
Instance Receiver: IConversionExpression (ConversionKind.CSharp, Explicit) (OperationKind.ConversionExpression, Type: T) (Syntax: '(T)d')
diff --git a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs
index 2d95ad35ba3b8a844a311959412e00772c4b47b1..9617323238a6d405166bb812944069cc77568cee 100644
--- a/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs
+++ b/src/Compilers/CSharp/Test/Semantic/IOperation/IOperationTests_IParameterReferenceExpression.cs
@@ -549,9 +549,8 @@ public void M(dynamic x, int y)
string expectedOperationTree = @"
IOperation: (OperationKind.None) (Syntax: 'x.M(y)')
Children(2):
- IOperation: (OperationKind.None) (Syntax: 'x.M')
- Children(1):
- IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: dynamic) (Syntax: 'x')
+ IDynamicMemberReferenceExpression (Member name: M, Containing Type: null) (OperationKind.DynamicAccessExpression, Type: dynamic) (Syntax: 'x.M')
+ Instance Receiver: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: dynamic) (Syntax: 'x')
IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y')
";
var expectedDiagnostics = DiagnosticDescription.None;