// 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 Xunit; namespace Microsoft.CodeAnalysis.CSharp.UnitTests { public partial class IOperationTests : SemanticModelTestBase { [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_TupleExpression() { string source = @" class Class1 { public void M(int x, int y) { var tuple = /**/(x, x + y)/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: '(x, x + y)') Children(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y') Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y') "; var expectedDiagnostics = new[] { // file.cs(6,13): warning CS0219: The variable 'tuple' is assigned but its value is never used // var tuple = /**/(x, x + y)/**/; Diagnostic(ErrorCode.WRN_UnreferencedVarAssg, "tuple").WithArguments("tuple").WithLocation(6, 13) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_TupleDeconstruction() { string source = @" class Point { public int X { get; } public int Y { get; } public Point(int x, int y) { X = x; Y = y; } public void Deconstruct(out int x, out int y) { x = X; y = Y; } } class Class1 { public void M(Point point) { /**/var (x, y) = point/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'var (x, y) = point') Children(2): IOperation: (OperationKind.None) (Syntax: 'var (x, y)') Children(2): ILocalReferenceExpression: x (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'x') ILocalReferenceExpression: y (OperationKind.LocalReferenceExpression, Type: System.Int32) (Syntax: 'y') IConversionExpression (ConversionKind.Invalid, Implicit) (OperationKind.ConversionExpression, Type: (System.Int32 x, System.Int32 y)) (Syntax: 'point') IParameterReferenceExpression: point (OperationKind.ParameterReferenceExpression, Type: Point) (Syntax: 'point') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_AnonymousObjectCreation() { string source = @" class Class1 { public void M(int x, string y) { var v = /**/new { Amount = x, Message = ""Hello"" + y }/**/; } } "; string expectedOperationTree = @" IAnonymousObjectCreationExpression (OperationKind.AnonymousObjectCreationExpression, Type: ) (Syntax: 'new { Amoun ... ello"" + y }') Initializers(2): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'Amount = x') Left: IPropertyReferenceExpression: System.Int32 .Amount { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'Amount') Instance Receiver: null Right: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.String) (Syntax: 'Message = ""Hello"" + y') Left: IPropertyReferenceExpression: System.String .Message { get; } (Static) (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'Message') Instance Receiver: null Right: IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: '""Hello"" + y') Left: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""Hello"") (Syntax: '""Hello""') Right: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 'y') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_QueryExpression() { string source = @" using System.Linq; using System.Collections.Generic; struct Customer { public string Name { get; set; } public string Address { get; set; } } class Class1 { public void M(List customers) { var result = /**/from cust in customers select cust.Name/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'from cust i ... t cust.Name') Children(1): IOperation: (OperationKind.None) (Syntax: 'select cust.Name') Children(1): IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Select(this System.Collections.Generic.IEnumerable source, System.Func selector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'select cust.Name') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from cust in customers') IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from cust in customers') IOperation: (OperationKind.None) (Syntax: 'from cust in customers') Children(1): IParameterReferenceExpression: customers (OperationKind.ParameterReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'customers') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'cust.Name') IConversionExpression (ConversionKind.CSharp, Implicit) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'cust.Name') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'cust.Name') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'cust.Name') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'cust.Name') IPropertyReferenceExpression: System.String Customer.Name { get; set; } (OperationKind.PropertyReferenceExpression, Type: System.String) (Syntax: 'cust.Name') Instance Receiver: IOperation: (OperationKind.None) (Syntax: 'cust') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_ObjectAndCollectionInitializer() { string source = @" using System.Collections.Generic; internal class Class { public int X { get; set; } public List Y { get; set; } public Dictionary Z { get; set; } public Class C { get; set; } public void M(int x, int y, int z) { var c = /**/new Class() { X = x, Y = { x, y, 3 }, Z = { { x, y } }, C = { X = z } }/**/; } } "; string expectedOperationTree = @" IObjectCreationExpression (Constructor: Class..ctor()) (OperationKind.ObjectCreationExpression, Type: Class) (Syntax: 'new Class() ... { X = z } }') Arguments(0) Initializer: IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: Class) (Syntax: '{ X = x, Y ... { X = z } }') Initializers(4): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'X = x') Left: IPropertyReferenceExpression: System.Int32 Class.X { get; set; } (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'X') Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'X') Right: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') IMemberInitializerExpression (OperationKind.MemberInitializerExpression, Type: System.Collections.Generic.List) (Syntax: 'Y = { x, y, 3 }') InitializedMember: IPropertyReferenceExpression: System.Collections.Generic.List Class.Y { get; set; } (OperationKind.PropertyReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'Y') Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'Y') Initializer: IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: System.Collections.Generic.List) (Syntax: '{ x, y, 3 }') Initializers(3): ICollectionElementInitializerExpression (AddMethod: void System.Collections.Generic.List.Add(System.Int32 item)) (IsDynamic: False) (OperationKind.CollectionElementInitializerExpression, Type: System.Void) (Syntax: 'x') Arguments(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') ICollectionElementInitializerExpression (AddMethod: void System.Collections.Generic.List.Add(System.Int32 item)) (IsDynamic: False) (OperationKind.CollectionElementInitializerExpression, Type: System.Void) (Syntax: 'y') Arguments(1): IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y') ICollectionElementInitializerExpression (AddMethod: void System.Collections.Generic.List.Add(System.Int32 item)) (IsDynamic: False) (OperationKind.CollectionElementInitializerExpression, Type: System.Void) (Syntax: '3') Arguments(1): ILiteralExpression (Text: 3) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3) (Syntax: '3') IMemberInitializerExpression (OperationKind.MemberInitializerExpression, Type: System.Collections.Generic.Dictionary) (Syntax: 'Z = { { x, y } }') InitializedMember: IPropertyReferenceExpression: System.Collections.Generic.Dictionary Class.Z { get; set; } (OperationKind.PropertyReferenceExpression, Type: System.Collections.Generic.Dictionary) (Syntax: 'Z') Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'Z') Initializer: IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: System.Collections.Generic.Dictionary) (Syntax: '{ { x, y } }') Initializers(1): ICollectionElementInitializerExpression (AddMethod: void System.Collections.Generic.Dictionary.Add(System.Int32 key, System.Int32 value)) (IsDynamic: False) (OperationKind.CollectionElementInitializerExpression, Type: System.Void) (Syntax: '{ x, y }') Arguments(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y') IMemberInitializerExpression (OperationKind.MemberInitializerExpression, Type: Class) (Syntax: 'C = { X = z }') InitializedMember: IPropertyReferenceExpression: Class Class.C { get; set; } (OperationKind.PropertyReferenceExpression, Type: Class) (Syntax: 'C') Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'C') Initializer: IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: Class) (Syntax: '{ X = z }') Initializers(1): ISimpleAssignmentExpression (OperationKind.SimpleAssignmentExpression, Type: System.Int32) (Syntax: 'X = z') Left: IPropertyReferenceExpression: System.Int32 Class.X { get; set; } (OperationKind.PropertyReferenceExpression, Type: System.Int32) (Syntax: 'X') Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'X') Right: IParameterReferenceExpression: z (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'z') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DelegateCreationExpressionWithLambdaArgument() { string source = @" using System; class Class { // Used parameter methods public void UsedParameterMethod1(Action a) { Action a2 = /**/new Action(() => { a(); })/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'new Action( ... })') Children(1): ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '() => ... }') IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }') IExpressionStatement (OperationKind.ExpressionStatement) (Syntax: 'a();') IInvocationExpression (virtual void System.Action.Invoke()) (OperationKind.InvocationExpression, Type: System.Void) (Syntax: 'a()') Instance Receiver: IParameterReferenceExpression: a (OperationKind.ParameterReferenceExpression, Type: System.Action) (Syntax: 'a') Arguments(0) IReturnStatement (OperationKind.ReturnStatement) (Syntax: '{ ... }') null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DelegateCreationExpressionWithMethodArgument() { string source = @" using System; class Class { public delegate void Delegate(int x, int y); public void Method(Delegate d) { var a = /**/new Delegate(Method2)/**/; } public void Method2(int x, int y) { } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'new Delegate(Method2)') Children(1): IOperation: (OperationKind.None) (Syntax: 'Method2') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DelegateCreationExpressionWithInvalidArgument() { string source = @" using System; class Class { public delegate void Delegate(int x, int y); public void Method(int x) { var a = /**/new Delegate(x)/**/; } } "; string expectedOperationTree = @" IInvalidExpression (OperationKind.InvalidExpression, Type: Class.Delegate, IsInvalid) (Syntax: 'new Delegate(x)') Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32, IsInvalid) (Syntax: 'x') "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0149: Method name expected // var a = /**/new Delegate(x)/**/; Diagnostic(ErrorCode.ERR_MethodNameExpected, "x").WithLocation(10, 40) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DynamicCollectionInitializer() { string source = @" using System.Collections.Generic; internal class Class { public dynamic X { get; set; } public void M(int x, int y) { var c = new Class() /**/{ X = { { x, y } } }/**/; } } "; string expectedOperationTree = @" IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: Class) (Syntax: '{ X = { { x, y } } }') Initializers(1): IMemberInitializerExpression (OperationKind.MemberInitializerExpression, Type: dynamic) (Syntax: 'X = { { x, y } }') InitializedMember: IPropertyReferenceExpression: dynamic Class.X { get; set; } (OperationKind.PropertyReferenceExpression, Type: dynamic) (Syntax: 'X') Instance Receiver: IInstanceReferenceExpression (InstanceReferenceKind.Implicit) (OperationKind.InstanceReferenceExpression, Type: Class) (Syntax: 'X') Initializer: IObjectOrCollectionInitializerExpression (OperationKind.ObjectOrCollectionInitializerExpression, Type: dynamic) (Syntax: '{ { x, y } }') Initializers(1): ICollectionElementInitializerExpression (IsDynamic: True) (OperationKind.CollectionElementInitializerExpression, Type: System.Void) (Syntax: '{ x, y }') Arguments(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_NameOfExpression() { string source = @" class Class1 { public string M(int x) { return /**/nameof(x)/**/; } } "; string expectedOperationTree = @" INameOfExpression (OperationKind.NameOfExpression, Type: System.String, Constant: ""x"") (Syntax: 'nameof(x)') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_PointerIndirectionExpression() { string source = @" class Class1 { public unsafe int M(int *x) { return /**/*x/**/; } } "; string expectedOperationTree = @" IPointerIndirectionReferenceExpression (OperationKind.PointerIndirectionReferenceExpression, Type: System.Int32) (Syntax: '*x') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32*) (Syntax: 'x') "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0227: Unsafe code may only appear if compiling with /unsafe // public unsafe int M(int *x) Diagnostic(ErrorCode.ERR_IllegalUnsafe, "M").WithLocation(4, 23) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_FixedLocalInitializer() { string source = @" using System.Collections.Generic; internal class Class { public unsafe void M(int[] array) { fixed (int* p /**/= array/**/) { *p = 1; } } } "; string expectedOperationTree = @" IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'p /**/= array') IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'p /**/= array') Variables: Local_1: System.Int32* p Initializer: IOperation: (OperationKind.None) (Syntax: 'array') Children(1): IParameterReferenceExpression: array (OperationKind.ParameterReferenceExpression, Type: System.Int32[]) (Syntax: 'array') "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0227: Unsafe code may only appear if compiling with /unsafe // public unsafe void M(int[] array) Diagnostic(ErrorCode.ERR_IllegalUnsafe, "M").WithLocation(6, 24) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_RefTypeOperator() { string source = @" class Class1 { public System.Type M(System.TypedReference x) { return /**/__reftype(x)/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: '__reftype(x)') Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.TypedReference) (Syntax: 'x') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_MakeRefOperator() { string source = @" class Class1 { public void M(System.Type x) { var y = /**/__makeref(x)/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: '__makeref(x)') Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Type) (Syntax: 'x') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_RefValueOperator() { string source = @" class Class1 { public void M(System.TypedReference x) { var y = /**/__refvalue(x, int)/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: '__refvalue(x, int)') Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.TypedReference) (Syntax: 'x') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DynamicIndexerAccess() { string source = @" class Class1 { public void M(dynamic d, int x) { var y /**/= d[x]/**/; } } "; string expectedOperationTree = @" IVariableDeclarationStatement (1 declarations) (OperationKind.VariableDeclarationStatement) (Syntax: 'var y /**/;') IVariableDeclaration (1 variables) (OperationKind.VariableDeclaration) (Syntax: 'var y /**/;') Variables: Local_1: dynamic y Initializer: IOperation: (OperationKind.None) (Syntax: 'd[x]') Children(2): IParameterReferenceExpression: d (OperationKind.ParameterReferenceExpression, Type: dynamic) (Syntax: 'd') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DynamicMemberAccess() { string source = @" class Class1 { public void M(dynamic x, int y) { var z = /**/x.M(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') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DynamicInvocation() { string source = @" class Class1 { public void M(dynamic x, int y) { var z = /**/x(y)/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'x(y)') Children(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: dynamic) (Syntax: 'x') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DynamicObjectCreation() { string source = @" internal class Class { public Class(Class x) { } public Class(string x) { } public void M(dynamic x) { var c = /**/new Class(x)/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'new Class(x)') Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: dynamic) (Syntax: 'x') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_StackAllocArrayCreation() { string source = @" using System.Collections.Generic; internal class Class { public unsafe void M(int x) { int* block = /**/stackalloc int[x]/**/; } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'stackalloc int[x]') Children(1): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0227: Unsafe code may only appear if compiling with /unsafe // public unsafe void M(int x) Diagnostic(ErrorCode.ERR_IllegalUnsafe, "M").WithLocation(6, 24) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_InterpolatedStringExpression() { string source = @" using System; internal class Class { public void M(string x, int y) { Console.WriteLine(/**/$""String {x,20} and {y:D3} and constant {1}""/**/); } } "; string expectedOperationTree = @" IInterpolatedStringExpression (OperationKind.InterpolatedStringExpression, Type: System.String) (Syntax: '$""String {x ... nstant {1}""') Parts(6): IInterpolatedStringText (OperationKind.InterpolatedStringText) (Syntax: 'String ') Text: ILiteralExpression (Text: String ) (OperationKind.LiteralExpression, Type: System.String, Constant: ""String "") (Syntax: 'String ') IInterpolation (OperationKind.Interpolation) (Syntax: '{x,20}') Expression: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 'x') Alignment: ILiteralExpression (Text: 20) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 20) (Syntax: '20') FormatString: null IInterpolatedStringText (OperationKind.InterpolatedStringText) (Syntax: ' and ') Text: ILiteralExpression (Text: and ) (OperationKind.LiteralExpression, Type: System.String, Constant: "" and "") (Syntax: ' and ') IInterpolation (OperationKind.Interpolation) (Syntax: '{y:D3}') Expression: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'y') Alignment: null FormatString: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: ""D3"") (Syntax: ':D3') IInterpolatedStringText (OperationKind.InterpolatedStringText) (Syntax: ' and constant ') Text: ILiteralExpression (Text: and constant ) (OperationKind.LiteralExpression, Type: System.String, Constant: "" and constant "") (Syntax: ' and constant ') IInterpolation (OperationKind.Interpolation) (Syntax: '{1}') Expression: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') Alignment: null FormatString: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_ThrowExpression() { string source = @" using System; internal class Class { public void M(string x) { var y = x ?? /**/throw new ArgumentNullException(nameof(x))/**/; } } "; string expectedOperationTree = @" IThrowExpression (OperationKind.ThrowExpression, Type: null) (Syntax: 'throw new A ... (nameof(x))') IObjectCreationExpression (Constructor: System.ArgumentNullException..ctor(System.String paramName)) (OperationKind.ObjectCreationExpression, Type: System.ArgumentNullException) (Syntax: 'new Argumen ... (nameof(x))') Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: paramName) (OperationKind.Argument) (Syntax: 'nameof(x)') INameOfExpression (OperationKind.NameOfExpression, Type: System.String, Constant: ""x"") (Syntax: 'nameof(x)') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.String) (Syntax: 'x') InConversion: null OutConversion: null Initializer: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_PatternSwitchStatement() { string source = @" internal class Class { public void M(int x) { switch (x) { /**/case var y when (x >= 10): break;/**/ } } } "; string expectedOperationTree = @" ISwitchStatement (1 cases) (OperationKind.SwitchStatement) (Syntax: 'switch (x) ... }') Switch expression: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') Sections: ISwitchCase (1 case clauses, 1 statements) (OperationKind.SwitchCase) (Syntax: 'case var y ... break;') Clauses: IPatternCaseClause (Label Symbol: case var y when (x >= 10):) (CaseKind.Pattern) (OperationKind.PatternCaseClause) (Syntax: 'case var y ... (x >= 10):') Pattern: IDeclarationPattern (Declared Symbol: System.Int32 y) (OperationKind.DeclarationPattern) (Syntax: 'var y') Guard Expression: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'x >= 10') Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') Body: IBranchStatement (BranchKind.Break) (OperationKind.BranchStatement) (Syntax: 'break;') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_DefaultPatternSwitchStatement() { string source = @" internal class Class { public void M(int x) { switch (x) { case var y when (x >= 10): break; /**/default:/**/ break; } } } "; string expectedOperationTree = @" ISwitchStatement (2 cases) (OperationKind.SwitchStatement) (Syntax: 'switch (x) ... }') Switch expression: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') Sections: ISwitchCase (1 case clauses, 1 statements) (OperationKind.SwitchCase) (Syntax: 'case var y ... break;') Clauses: IPatternCaseClause (Label Symbol: case var y when (x >= 10):) (CaseKind.Pattern) (OperationKind.PatternCaseClause) (Syntax: 'case var y ... (x >= 10):') Pattern: IDeclarationPattern (Declared Symbol: System.Int32 y) (OperationKind.DeclarationPattern) (Syntax: 'var y') Guard Expression: IBinaryOperatorExpression (BinaryOperationKind.IntegerGreaterThanOrEqual) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'x >= 10') Left: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') Body: IBranchStatement (BranchKind.Break) (OperationKind.BranchStatement) (Syntax: 'break;') ISwitchCase (1 case clauses, 1 statements) (OperationKind.SwitchCase) (Syntax: 'default:/*< ... break;') Clauses: IDefaultCaseClause (CaseKind.Default) (OperationKind.DefaultCaseClause) (Syntax: 'default:') Body: IBranchStatement (BranchKind.Break) (OperationKind.BranchStatement) (Syntax: 'break;') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_UserDefinedLogicalConditionalOperator() { string source = @" class A { public static bool operator true(A o) { return true; } public static bool operator false(A o) { return false; } } class B : A { public static B operator &(B x, B y) { return x; } } class C : B { public static C operator |(C x, C y) { return x; } } class P { static void M(C x, C y) { if (/**/x && y/**/) { } } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: 'x && y') Children(2): IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: B) (Syntax: 'x') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'x') IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: B) (Syntax: 'y') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: C) (Syntax: 'y') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_NoPiaObjectCreation() { var sources0 = @" using System; using System.Runtime.InteropServices; [assembly: ImportedFromTypeLib(""_.dll"")] [assembly: Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58257"")] [ComImport()] [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58277"")] [CoClass(typeof(C))] public interface I { int P { get; set; } } [Guid(""f9c2d51d-4f44-45f0-9eda-c9d599b58278"")] public class C { public C(object o) { } } "; var sources1 = @" struct S { public I F(object x) { return /**/new I(x)/**/; } } "; var compilation0 = CreateStandardCompilation(sources0); compilation0.VerifyDiagnostics(); var compilation1 = CreateStandardCompilation( sources1, references: new[] { MscorlibRef, SystemRef, compilation0.EmitToImageReference(embedInteropTypes: true) }); string expectedOperationTree = @" IOperation: (OperationKind.None, IsInvalid) (Syntax: 'new I(x)') "; var expectedDiagnostics = new DiagnosticDescription[] { // (6,25): error CS1729: 'I' does not contain a constructor that takes 1 arguments // return /**/new I(x)/**/; Diagnostic(ErrorCode.ERR_BadCtorArgCount, "(x)").WithArguments("I", "1").WithLocation(6, 25) }; VerifyOperationTreeAndDiagnosticsForTest(compilation1, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(8884, "https://github.com/dotnet/roslyn/issues/8884")] public void ParameterReference_ArgListOperator() { string source = @" using System; class C { static void Method(int x, bool y) { M(1, /**/__arglist(x, y)/**/); } static void M(int x, __arglist) { } } "; string expectedOperationTree = @" IOperation: (OperationKind.None) (Syntax: '__arglist(x, y)') Children(2): IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'x') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Boolean) (Syntax: 'y') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(19790, "https://github.com/dotnet/roslyn/issues/19790")] public void ParameterReference_IsPatternExpression() { string source = @" class Class1 { public void Method1(object x) { if (/**/x is int y/**/) { } } } "; string expectedOperationTree = @" IIsPatternExpression (OperationKind.IsPatternExpression, Type: System.Boolean) (Syntax: 'x is int y') Expression: IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Object) (Syntax: 'x') Pattern: IDeclarationPattern (Declared Symbol: System.Int32 y) (OperationKind.DeclarationPattern) (Syntax: 'int y') "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(19902, "https://github.com/dotnet/roslyn/issues/19902")] public void ParameterReference_LocalFunctionStatement() { string source = @" using System; using System.Collections.Generic; class Class { static IEnumerable MyIterator(IEnumerable source, Func predicate) { /**/IEnumerable Iterator() { foreach (var element in source) if (predicate(element)) yield return element; }/**/ return Iterator(); } } "; string expectedOperationTree = @" ILocalFunctionStatement (Local Function: System.Collections.Generic.IEnumerable Iterator()) (OperationKind.LocalFunctionStatement) (Syntax: 'IEnumerable ... }') IBlockStatement (2 statements) (OperationKind.BlockStatement) (Syntax: '{ ... }') IForEachLoopStatement (Iteration variable: T element) (LoopKind.ForEach) (OperationKind.LoopStatement) (Syntax: 'foreach (va ... rn element;') Collection: IConversionExpression (ConversionKind.Cast, Implicit) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'source') IParameterReferenceExpression: source (OperationKind.ParameterReferenceExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'source') Body: IIfStatement (OperationKind.IfStatement) (Syntax: 'if (predica ... rn element;') Condition: IInvocationExpression (virtual System.Boolean System.Func.Invoke(T arg)) (OperationKind.InvocationExpression, Type: System.Boolean) (Syntax: 'predicate(element)') Instance Receiver: IParameterReferenceExpression: predicate (OperationKind.ParameterReferenceExpression, Type: System.Func) (Syntax: 'predicate') Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: arg) (OperationKind.Argument) (Syntax: 'element') ILocalReferenceExpression: element (OperationKind.LocalReferenceExpression, Type: T) (Syntax: 'element') InConversion: null OutConversion: null IfTrue: IReturnStatement (OperationKind.YieldReturnStatement) (Syntax: 'yield return element;') ILocalReferenceExpression: element (OperationKind.LocalReferenceExpression, Type: T) (Syntax: 'element') IfFalse: null IReturnStatement (OperationKind.YieldBreakStatement) (Syntax: '{ ... }') null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } } }