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;