// 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 System; using System.IO; using System.Linq; using Microsoft.CodeAnalysis.CSharp.Symbols; 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 QueryTests : CompilingTestBase { [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void DegenerateQueryExpression() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(1, 2, 3, 4, 5, 6, 7); List1 r = from i in c select i; if (ReferenceEquals(c, r)) throw new Exception(); // List1 r = c.Select(i => i); Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[1, 2, 3, 4, 5, 6, 7]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void FromClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c = new List() {1, 2, 3, 4, 5, 6, 7}; var r = /**/from i in c select i/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c select i') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select i') ReducedExpression: 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 i') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from i in c') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from i in c') ReducedExpression: ILocalReferenceExpression: c (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'i') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'i') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void QueryContinuation() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(1, 2, 3, 4, 5, 6, 7); List1 r = from i in c select i into q select q; if (ReferenceEquals(c, r)) throw new Exception(); // List1 r = c.Select(i => i); Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[1, 2, 3, 4, 5, 6, 7]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void QueryContinuation_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c = new List() {1, 2, 3, 4, 5, 6, 7}; var r = /**/from i in c select i into q select q/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c ... q select q') LastClauseOrContinuation: IQueryContinuation (Declared symbol: ? q) (OperationKind.QueryContinuation) (Syntax: 'into q select q') Query Body: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select q') ReducedExpression: 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 q') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'select i') ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select i') ReducedExpression: 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 i') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from i in c') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from i in c') ReducedExpression: ILocalReferenceExpression: c (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'i') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'i') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'q') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'q') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'q') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'q') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'q') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'q') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void Select() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(1, 2, 3, 4, 5, 6, 7); List1 r = from i in c select i+1; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[2, 3, 4, 5, 6, 7, 8]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void SelectClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c = new List() {1, 2, 3, 4, 5, 6, 7}; var r = /**/from i in c select i+1/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c select i+1') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select i+1') ReducedExpression: 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 i+1') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from i in c') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from i in c') ReducedExpression: ILocalReferenceExpression: c (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'i+1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i+1') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i+1') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i+1') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i+1') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'i+1') Left: IOperation: (OperationKind.None) (Syntax: 'i') Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void GroupBy01() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(1, 2, 3, 4, 5, 6, 7); var r = from i in c group i by i % 2; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[1:[1, 3, 5, 7], 0:[2, 4, 6]]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void GroupByClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c = new List() {1, 2, 3, 4, 5, 6, 7}; var r = /**/from i in c group i by i % 2/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable>) (Syntax: 'from i in c ... i by i % 2') LastClauseOrContinuation: IGroupByQueryClause (Clause kind: GroupByClause) (OperationKind.QueryClause) (Syntax: 'group i by i % 2') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable> System.Linq.Enumerable.GroupBy(this System.Collections.Generic.IEnumerable source, System.Func keySelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable>) (Syntax: 'group i by i % 2') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from i in c') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from i in c') ReducedExpression: ILocalReferenceExpression: c (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: keySelector) (OperationKind.Argument) (Syntax: 'i % 2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i % 2') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i % 2') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i % 2') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i % 2') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerRemainder) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'i % 2') Left: IOperation: (OperationKind.None) (Syntax: 'i') Right: ILiteralExpression (Text: 2) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 2) (Syntax: '2') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void GroupBy02() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(1, 2, 3, 4, 5, 6, 7); var r = from i in c group 10+i by i % 2; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[1:[11, 13, 15, 17], 0:[12, 14, 16]]"); } [Fact] public void Cast() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(1, 2, 3, 4, 5, 6, 7); List1 r = from int i in c select i; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[1, 2, 3, 4, 5, 6, 7]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void CastInFromClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c = new List() {1, 2, 3, 4, 5, 6, 7}; var r = /**/from int i in c select i/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int i in c select i') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select i') ReducedExpression: 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 i') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int i in c') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int i in c') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int i in c') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'i') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'i') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact] public void Where() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(1, 2, 3, 4, 5, 6, 7); List1 r = from int i in c where i < 5 select i; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[1, 2, 3, 4]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void WhereClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c = new List() {1, 2, 3, 4, 5, 6, 7}; var r = /**/from int i in c where i < 5 select i/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int i ... 5 select i') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select i') ReducedExpression: IWhereQueryClause (Clause kind: WhereClause) (OperationKind.QueryClause) (Syntax: 'where i < 5') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Where(this System.Collections.Generic.IEnumerable source, System.Func predicate)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'where i < 5') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int i in c') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int i in c') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int i in c') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: predicate) (OperationKind.Argument) (Syntax: 'i < 5') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i < 5') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i < 5') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i < 5') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i < 5') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerLessThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'i < 5') Left: IOperation: (OperationKind.None) (Syntax: 'i') Right: ILiteralExpression (Text: 5) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 5) (Syntax: '5') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void FromJoinSelect() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c1 = new List1(1, 2, 3, 4, 5, 7); List1 c2 = new List1(10, 30, 40, 50, 60, 70); List1 r = from x1 in c1 join x2 in c2 on x1 equals x2/10 select x1+x2; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[11, 33, 44, 55, 77]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void FromJoinSelect_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c1 = new List() {1, 2, 3, 4, 5, 6, 7}; List c2 = new List() {10, 30, 40, 50, 60, 70}; var r = /**/from x1 in c1 join x2 in c2 on x1 equals x2/10 select x1+x2/**/; } } "; // BoundRangeVariable still doesn't have an IOperation API: https://github.com/dotnet/roslyn/issues/21238 string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from x1 in ... elect x1+x2') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select x1+x2') ReducedExpression: IJoinQueryClause (Clause kind: JoinClause) (OperationKind.QueryClause) (Syntax: 'join x2 in ... quals x2/10') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Join(this System.Collections.Generic.IEnumerable outer, System.Collections.Generic.IEnumerable inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'join x2 in ... quals x2/10') Instance Receiver: null Arguments(5): IArgument (ArgumentKind.Explicit, Matching Parameter: outer) (OperationKind.Argument) (Syntax: 'from x1 in c1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from x1 in c1') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from x1 in c1') ReducedExpression: ILocalReferenceExpression: c1 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: inner) (OperationKind.Argument) (Syntax: 'c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c2 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c2') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: outerKeySelector) (OperationKind.Argument) (Syntax: 'x1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'x1') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x1') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x1') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x1') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'x1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: innerKeySelector) (OperationKind.Argument) (Syntax: 'x2/10') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'x2/10') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x2/10') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x2/10') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x2/10') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerDivide) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x2/10') Left: IOperation: (OperationKind.None) (Syntax: 'x2') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'x1+x2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'x1+x2') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x1+x2') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x1+x2') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x1+x2') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x1+x2') Left: IOperation: (OperationKind.None) (Syntax: 'x1') Right: IOperation: (OperationKind.None) (Syntax: 'x2') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void OrderBy() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(28, 51, 27, 84, 27, 27, 72, 64, 55, 46, 39); var r = from i in c orderby i/10 descending, i%10 select i; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[84, 72, 64, 51, 55, 46, 39, 27, 27, 27, 28]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void OrderByClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c = new List() {1, 2, 3, 4, 5, 6, 7}; var r = /**/from i in c orderby i/10 descending, i%10 select i/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Linq.IOrderedEnumerable) (Syntax: 'from i in c ... select i') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select i') ReducedExpression: IOrderByQueryClause (Clause kind: OrderByClause) (OperationKind.QueryClause) (Syntax: 'orderby i/1 ... nding, i%10') ReducedExpression: IOrderingExpression (Order kind: Ascending) (OperationKind.OrderingExpression, Type: System.Linq.IOrderedEnumerable) (Syntax: 'i%10') Expression: IInvocationExpression (System.Linq.IOrderedEnumerable System.Linq.Enumerable.ThenBy(this System.Linq.IOrderedEnumerable source, System.Func keySelector)) (OperationKind.InvocationExpression, Type: System.Linq.IOrderedEnumerable) (Syntax: 'i%10') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'i/10 descending') IOrderingExpression (Order kind: Descending) (OperationKind.OrderingExpression, Type: System.Linq.IOrderedEnumerable) (Syntax: 'i/10 descending') Expression: IInvocationExpression (System.Linq.IOrderedEnumerable System.Linq.Enumerable.OrderByDescending(this System.Collections.Generic.IEnumerable source, System.Func keySelector)) (OperationKind.InvocationExpression, Type: System.Linq.IOrderedEnumerable) (Syntax: 'i/10 descending') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from i in c') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from i in c') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from i in c') ReducedExpression: ILocalReferenceExpression: c (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: keySelector) (OperationKind.Argument) (Syntax: 'i/10') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i/10') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i/10') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i/10') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i/10') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerDivide) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'i/10') Left: IOperation: (OperationKind.None) (Syntax: 'i') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: keySelector) (OperationKind.Argument) (Syntax: 'i%10') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'i%10') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i%10') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i%10') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i%10') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerRemainder) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'i%10') Left: IOperation: (OperationKind.None) (Syntax: 'i') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void GroupJoin() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c1 = new List1(1, 2, 3, 4, 5, 7); List1 c2 = new List1(12, 34, 42, 51, 52, 66, 75); List1 r = from x1 in c1 join x2 in c2 on x1 equals x2 / 10 into g select x1 + "":"" + g.ToString(); Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[1:[12], 2:[], 3:[34], 4:[42], 5:[51, 52], 7:[75]]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void GroupJoinClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c1 = new List{1, 2, 3, 4, 5, 7}; List c2 = new List{12, 34, 42, 51, 52, 66, 75}; var r = /**/from x1 in c1 join x2 in c2 on x1 equals x2 / 10 into g select x1 + "":"" + g.ToString()/**/; } } "; // BoundRangeVariable still doesn't have an IOperation API: https://github.com/dotnet/roslyn/issues/21238 string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from x1 in ... .ToString()') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select x1 + ... .ToString()') ReducedExpression: IJoinQueryClause (Clause kind: JoinClause) (OperationKind.QueryClause) (Syntax: 'join x2 in ... / 10 into g') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.GroupJoin(this System.Collections.Generic.IEnumerable outer, System.Collections.Generic.IEnumerable inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func, System.String> resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'join x2 in ... / 10 into g') Instance Receiver: null Arguments(5): IArgument (ArgumentKind.Explicit, Matching Parameter: outer) (OperationKind.Argument) (Syntax: 'from x1 in c1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from x1 in c1') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from x1 in c1') ReducedExpression: ILocalReferenceExpression: c1 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: inner) (OperationKind.Argument) (Syntax: 'c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c2 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c2') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: outerKeySelector) (OperationKind.Argument) (Syntax: 'x1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'x1') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x1') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x1') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x1') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'x1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: innerKeySelector) (OperationKind.Argument) (Syntax: 'x2 / 10') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'x2 / 10') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x2 / 10') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x2 / 10') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x2 / 10') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerDivide) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x2 / 10') Left: IOperation: (OperationKind.None) (Syntax: 'x2') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'into g') IJoinIntoQueryClause (Clause kind: JoinIntoClause) (OperationKind.QueryClause) (Syntax: 'into g') ReducedExpression: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func, System.String>) (Syntax: 'x1 + "":"" + g.ToString()') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x1 + "":"" + g.ToString()') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x1 + "":"" + g.ToString()') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x1 + "":"" + g.ToString()') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: 'x1 + "":"" + g.ToString()') Left: IBinaryOperatorExpression (BinaryOperationKind.StringConcatenate) (OperationKind.BinaryOperatorExpression, Type: System.String) (Syntax: 'x1 + "":""') Left: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Object) (Syntax: 'x1') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IOperation: (OperationKind.None) (Syntax: 'x1') Right: ILiteralExpression (OperationKind.LiteralExpression, Type: System.String, Constant: "":"") (Syntax: '"":""') Right: IInvocationExpression (virtual System.String System.Object.ToString()) (OperationKind.InvocationExpression, Type: System.String) (Syntax: 'g.ToString()') Instance Receiver: IOperation: (OperationKind.None) (Syntax: 'g') Arguments(0) InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void SelectMany01() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c1 = new List1(1, 2, 3); List1 c2 = new List1(10, 20, 30); List1 r = from x in c1 from y in c2 select x + y; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[11, 21, 31, 12, 22, 32, 13, 23, 33]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void SelectMany_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c1 = new List{1, 2, 3, 4, 5, 7}; List c2 = new List{12, 34, 42, 51, 52, 66, 75}; var r = /**/from x in c1 from y in c2 select x + y/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from x in c ... elect x + y') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select x + y') ReducedExpression: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from y in c2') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.SelectMany(this System.Collections.Generic.IEnumerable source, System.Func> collectionSelector, System.Func resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from y in c2') Instance Receiver: null Arguments(3): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from x in c1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from x in c1') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from x in c1') ReducedExpression: ILocalReferenceExpression: c1 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: collectionSelector) (OperationKind.Argument) (Syntax: 'from y in c2') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from y in c2') ReducedExpression: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'c2') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'c2') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'c2') ReturnedValue: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c2 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c2') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'x + y') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'x + y') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x + y') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x + y') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x + y') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: IOperation: (OperationKind.None) (Syntax: 'y') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void SelectMany02() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c1 = new List1(1, 2, 3); List1 c2 = new List1(10, 20, 30); List1 r = from x in c1 from int y in c2 select x + y; Console.WriteLine(r); } }"; CompileAndVerify(csSource, expectedOutput: "[11, 21, 31, 12, 22, 32, 13, 23, 33]"); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void Let01() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c1 = new List1(1, 2, 3); List1 r1 = from int x in c1 let g = x * 10 let z = g + x*100 select x + z; System.Console.WriteLine(r1); } }"; CompileAndVerify(csSource, expectedOutput: "[111, 222, 333]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void LetClause_IOperation() { string source = @" using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { List c1 = new List{1, 2, 3, 4, 5, 7}; var r = /**/from int x in c1 let g = x * 10 let z = g + x*100 select x + z/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int x ... elect x + z') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select x + z') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Select< <>h__TransparentIdentifier0, System.Int32 z>, System.Int32>(this System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z>> source, System.Func< <>h__TransparentIdentifier0, System.Int32 z>, System.Int32> selector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'select x + z') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'let z = g + x*100') ILetQueryClause (Clause kind: LetClause) (OperationKind.QueryClause) (Syntax: 'let z = g + x*100') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z>> System.Linq.Enumerable.Select<, <>h__TransparentIdentifier0, System.Int32 z>>(this System.Collections.Generic.IEnumerable<> source, System.Func<, <>h__TransparentIdentifier0, System.Int32 z>> selector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z>>) (Syntax: 'let z = g + x*100') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'let g = x * 10') ILetQueryClause (Clause kind: LetClause) (OperationKind.QueryClause) (Syntax: 'let g = x * 10') ReducedExpression: 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: 'let g = x * 10') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int x in c1') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int x in c1') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int x in c1') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c1') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c1 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c1') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'x * 10') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>) (Syntax: 'x * 10') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x * 10') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x * 10') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x * 10') ReturnedValue: IObjectCreationExpression (Constructor: ..ctor(System.Int32 x, System.Int32 g)) (OperationKind.ObjectCreationExpression, Type: ) (Syntax: 'let g = x * 10') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: 'let g = x * 10') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'let g = x * 10') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: g) (OperationKind.Argument) (Syntax: 'x * 10') IBinaryOperatorExpression (BinaryOperationKind.IntegerMultiply) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x * 10') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') InConversion: null OutConversion: null Initializer: null InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'g + x*100') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func<, <>h__TransparentIdentifier0, System.Int32 z>>) (Syntax: 'g + x*100') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'g + x*100') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'g + x*100') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'g + x*100') ReturnedValue: IObjectCreationExpression (Constructor: <>h__TransparentIdentifier0, System.Int32 z>..ctor( <>h__TransparentIdentifier0, System.Int32 z)) (OperationKind.ObjectCreationExpression, Type: <>h__TransparentIdentifier0, System.Int32 z>) (Syntax: 'let z = g + x*100') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: <>h__TransparentIdentifier0) (OperationKind.Argument) (Syntax: 'let z = g + x*100') IParameterReferenceExpression: <>h__TransparentIdentifier0 (OperationKind.ParameterReferenceExpression, Type: ) (Syntax: 'let z = g + x*100') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: z) (OperationKind.Argument) (Syntax: 'g + x*100') IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'g + x*100') Left: IOperation: (OperationKind.None) (Syntax: 'g') Right: IBinaryOperatorExpression (BinaryOperationKind.IntegerMultiply) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x*100') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: ILiteralExpression (Text: 100) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 100) (Syntax: '100') InConversion: null OutConversion: null Initializer: null InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'x + z') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func< <>h__TransparentIdentifier0, System.Int32 z>, System.Int32>) (Syntax: 'x + z') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x + z') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x + z') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x + z') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + z') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: IOperation: (OperationKind.None) (Syntax: 'z') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void TransparentIdentifiers_FromLet() { var csSource = @" using C = List1;" + LINQ + @" class Query { public static void Main(string[] args) { C c1 = new C(1, 2, 3); C c2 = new C(10, 20, 30); C c3 = new C(100, 200, 300); C r1 = from int x in c1 from int y in c2 from int z in c3 let g = x + y + z where (x + y / 10 + z / 100) < 6 select g; Console.WriteLine(r1); } }"; CompileAndVerify(csSource, expectedOutput: "[111, 211, 311, 121, 221, 131, 112, 212, 122, 113]"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void TransparentIdentifiers_FromLet_IOperation() { string source = @" using C = System.Collections.Generic.List; using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { C c1 = new C{1, 2, 3}; C c2 = new C{10, 20, 30}; C c3 = new C{100, 200, 300}; var r1 = /**/from int x in c1 from int y in c2 from int z in c3 let g = x + y + z where (x + y / 10 + z / 100) < 6 select g/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int x ... select g') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select g') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Select< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>, System.Int32>(this System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>> source, System.Func< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>, System.Int32> selector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'select g') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'where (x + ... / 100) < 6') IWhereQueryClause (Clause kind: WhereClause) (OperationKind.QueryClause) (Syntax: 'where (x + ... / 100) < 6') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>> System.Linq.Enumerable.Where< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>>(this System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>> source, System.Func< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>, System.Boolean> predicate)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>>) (Syntax: 'where (x + ... / 100) < 6') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'let g = x + y + z') ILetQueryClause (Clause kind: LetClause) (OperationKind.QueryClause) (Syntax: 'let g = x + y + z') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>> System.Linq.Enumerable.Select< <>h__TransparentIdentifier0, System.Int32 z>, <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>>(this System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z>> source, System.Func< <>h__TransparentIdentifier0, System.Int32 z>, <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>> selector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>>) (Syntax: 'let g = x + y + z') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int z in c3') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int z in c3') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z>> System.Linq.Enumerable.SelectMany<, System.Int32, <>h__TransparentIdentifier0, System.Int32 z>>(this System.Collections.Generic.IEnumerable<> source, System.Func<, System.Collections.Generic.IEnumerable> collectionSelector, System.Func<, System.Int32, <>h__TransparentIdentifier0, System.Int32 z>> resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable< <>h__TransparentIdentifier0, System.Int32 z>>) (Syntax: 'from int z in c3') Instance Receiver: null Arguments(3): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int y in c2') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int y in c2') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable<> System.Linq.Enumerable.SelectMany>(this System.Collections.Generic.IEnumerable source, System.Func> collectionSelector, System.Func> resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable<>) (Syntax: 'from int y in c2') Instance Receiver: null Arguments(3): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int x in c1') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int x in c1') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int x in c1') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c1') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c1 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c1') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: collectionSelector) (OperationKind.Argument) (Syntax: 'c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'c2') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'c2') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'c2') ReturnedValue: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'c2') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c2 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c2') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'from int y in c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>) (Syntax: 'from int y in c2') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'from int y in c2') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'from int y in c2') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'from int y in c2') ReturnedValue: IObjectCreationExpression (Constructor: ..ctor(System.Int32 x, System.Int32 y)) (OperationKind.ObjectCreationExpression, Type: ) (Syntax: 'from int y in c2') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: 'from int y in c2') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'from int y in c2') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument) (Syntax: 'from int y in c2') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'from int y in c2') InConversion: null OutConversion: null Initializer: null InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: collectionSelector) (OperationKind.Argument) (Syntax: 'c3') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func<, System.Collections.Generic.IEnumerable>) (Syntax: 'c3') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'c3') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'c3') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'c3') ReturnedValue: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'c3') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c3') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c3') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c3 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c3') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'from int z in c3') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func<, System.Int32, <>h__TransparentIdentifier0, System.Int32 z>>) (Syntax: 'from int z in c3') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'from int z in c3') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'from int z in c3') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'from int z in c3') ReturnedValue: IObjectCreationExpression (Constructor: <>h__TransparentIdentifier0, System.Int32 z>..ctor( <>h__TransparentIdentifier0, System.Int32 z)) (OperationKind.ObjectCreationExpression, Type: <>h__TransparentIdentifier0, System.Int32 z>) (Syntax: 'from int z in c3') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: <>h__TransparentIdentifier0) (OperationKind.Argument) (Syntax: 'from int z in c3') IParameterReferenceExpression: <>h__TransparentIdentifier0 (OperationKind.ParameterReferenceExpression, Type: ) (Syntax: 'from int z in c3') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: z) (OperationKind.Argument) (Syntax: 'from int z in c3') IParameterReferenceExpression: z (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'from int z in c3') InConversion: null OutConversion: null Initializer: null InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'x + y + z') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func< <>h__TransparentIdentifier0, System.Int32 z>, <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>>) (Syntax: 'x + y + z') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x + y + z') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x + y + z') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x + y + z') ReturnedValue: IObjectCreationExpression (Constructor: <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>..ctor( <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g)) (OperationKind.ObjectCreationExpression, Type: <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>) (Syntax: 'let g = x + y + z') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: <>h__TransparentIdentifier1) (OperationKind.Argument) (Syntax: 'let g = x + y + z') IParameterReferenceExpression: <>h__TransparentIdentifier1 (OperationKind.ParameterReferenceExpression, Type: <>h__TransparentIdentifier0, System.Int32 z>) (Syntax: 'let g = x + y + z') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: g) (OperationKind.Argument) (Syntax: 'x + y + z') IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y + z') Left: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: IOperation: (OperationKind.None) (Syntax: 'y') Right: IOperation: (OperationKind.None) (Syntax: 'z') InConversion: null OutConversion: null Initializer: null InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: predicate) (OperationKind.Argument) (Syntax: '(x + y / 10 ... / 100) < 6') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>, System.Boolean>) (Syntax: '(x + y / 10 ... / 100) < 6') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '(x + y / 10 ... / 100) < 6') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '(x + y / 10 ... / 100) < 6') IReturnStatement (OperationKind.ReturnStatement) (Syntax: '(x + y / 10 ... / 100) < 6') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerLessThan) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: '(x + y / 10 ... / 100) < 6') Left: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y / 10 + z / 100') Left: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y / 10') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: IBinaryOperatorExpression (BinaryOperationKind.IntegerDivide) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'y / 10') Left: IOperation: (OperationKind.None) (Syntax: 'y') Right: ILiteralExpression (Text: 10) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 10) (Syntax: '10') Right: IBinaryOperatorExpression (BinaryOperationKind.IntegerDivide) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'z / 100') Left: IOperation: (OperationKind.None) (Syntax: 'z') Right: ILiteralExpression (Text: 100) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 100) (Syntax: '100') Right: ILiteralExpression (Text: 6) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 6) (Syntax: '6') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument) (Syntax: 'g') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func< <>h__TransparentIdentifier0, System.Int32 z> <>h__TransparentIdentifier1, System.Int32 g>, System.Int32>) (Syntax: 'g') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'g') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'g') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'g') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'g') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void TransparentIdentifiers_Join01() { var csSource = @" using C = List1;" + LINQ + @" class Query { public static void Main(string[] args) { C c1 = new C(1, 2, 3); C c2 = new C(10, 20, 30); C r1 = from int x in c1 join y in c2 on x equals y/10 let z = x+y select z; Console.WriteLine(r1); } }"; CompileAndVerify(csSource, expectedOutput: "[11, 22, 33]"); } [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void TransparentIdentifiers_Join02() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c1 = new List1(1, 2, 3, 4, 5, 7); List1 c2 = new List1(12, 34, 42, 51, 52, 66, 75); List1 r1 = from x1 in c1 join x2 in c2 on x1 equals x2 / 10 into g where x1 < 7 select x1 + "":"" + g.ToString(); Console.WriteLine(r1); } }"; CompileAndVerify(csSource, expectedOutput: "[1:[12], 2:[], 3:[34], 4:[42], 5:[51, 52]]"); } [Fact] public void CodegenBug() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c1 = new List1(1, 2, 3, 4, 5, 7); List1 c2 = new List1(12, 34, 42, 51, 52, 66, 75); List1>> r1 = c1 .GroupJoin(c2, x1 => x1, x2 => x2 / 10, (x1, g) => new Tuple>(x1, g)) ; Func1>, bool> condition = (Tuple> TR1) => TR1.Item1 < 7; List1>> r2 = r1 .Where(condition) ; Func1>, string> map = (Tuple> TR1) => TR1.Item1.ToString() + "":"" + TR1.Item2.ToString(); List1 r3 = r2 .Select(map) ; string r4 = r3.ToString(); Console.WriteLine(r4); return; } }"; CompileAndVerify(csSource, expectedOutput: "[1:[12], 2:[], 3:[34], 4:[42], 5:[51, 52]]"); } [Fact] public void RangeVariables01() { var csSource = @" using C = List1;" + LINQ + @" class Query { public static void Main(string[] args) { C c1 = new C(1, 2, 3); C c2 = new C(10, 20, 30); C c3 = new C(100, 200, 300); C r1 = from int x in c1 from int y in c2 from int z in c3 select x + y + z; Console.WriteLine(r1); } }"; var compilation = CreateStandardCompilation(csSource); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Query").Single(); dynamic methodM = (MethodDeclarationSyntax)classC.Members[0]; QueryExpressionSyntax q = methodM.Body.Statements[3].Declaration.Variables[0].Initializer.Value; var info0 = model.GetQueryClauseInfo(q.FromClause); var x = model.GetDeclaredSymbol(q.FromClause); Assert.Equal(SymbolKind.RangeVariable, x.Kind); Assert.Equal("x", x.Name); Assert.Equal("Cast", info0.CastInfo.Symbol.Name); Assert.NotEqual(MethodKind.ReducedExtension, ((IMethodSymbol)info0.CastInfo.Symbol).MethodKind); Assert.Null(info0.OperationInfo.Symbol); var info1 = model.GetQueryClauseInfo(q.Body.Clauses[0]); var y = model.GetDeclaredSymbol(q.Body.Clauses[0]); Assert.Equal(SymbolKind.RangeVariable, y.Kind); Assert.Equal("y", y.Name); Assert.Equal("Cast", info1.CastInfo.Symbol.Name); Assert.Equal("SelectMany", info1.OperationInfo.Symbol.Name); Assert.NotEqual(MethodKind.ReducedExtension, ((IMethodSymbol)info1.OperationInfo.Symbol).MethodKind); var info2 = model.GetQueryClauseInfo(q.Body.Clauses[1]); var z = model.GetDeclaredSymbol(q.Body.Clauses[1]); Assert.Equal(SymbolKind.RangeVariable, z.Kind); Assert.Equal("z", z.Name); Assert.Equal("Cast", info2.CastInfo.Symbol.Name); Assert.Equal("SelectMany", info2.OperationInfo.Symbol.Name); var info3 = model.GetSemanticInfoSummary(q.Body.SelectOrGroup); Assert.NotNull(info3); // what about info3's contents ??? var xPyPz = (q.Body.SelectOrGroup as SelectClauseSyntax).Expression as BinaryExpressionSyntax; var xPy = xPyPz.Left as BinaryExpressionSyntax; Assert.Equal(x, model.GetSemanticInfoSummary(xPy.Left).Symbol); Assert.Equal(y, model.GetSemanticInfoSummary(xPy.Right).Symbol); Assert.Equal(z, model.GetSemanticInfoSummary(xPyPz.Right).Symbol); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void RangeVariables_IOperation() { string source = @" using C = System.Collections.Generic.List; using System.Collections.Generic; using System.Linq; class Query { public static void Main(string[] args) { C c1 = new C{1, 2, 3}; C c2 = new C{10, 20, 30}; C c3 = new C{100, 200, 300}; var r1 = /**/from int x in c1 from int y in c2 from int z in c3 select x + y + z/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int x ... t x + y + z') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select x + y + z') ReducedExpression: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int z in c3') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.SelectMany<, System.Int32, System.Int32>(this System.Collections.Generic.IEnumerable<> source, System.Func<, System.Collections.Generic.IEnumerable> collectionSelector, System.Func<, System.Int32, System.Int32> resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int z in c3') Instance Receiver: null Arguments(3): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int y in c2') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int y in c2') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable<> System.Linq.Enumerable.SelectMany>(this System.Collections.Generic.IEnumerable source, System.Func> collectionSelector, System.Func> resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable<>) (Syntax: 'from int y in c2') Instance Receiver: null Arguments(3): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from int x in c1') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int x in c1') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int x in c1') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c1') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c1') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c1 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c1') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: collectionSelector) (OperationKind.Argument) (Syntax: 'c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'c2') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'c2') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'c2') ReturnedValue: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'c2') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c2') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c2 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c2') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'from int y in c2') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>) (Syntax: 'from int y in c2') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'from int y in c2') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'from int y in c2') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'from int y in c2') ReturnedValue: IObjectCreationExpression (Constructor: ..ctor(System.Int32 x, System.Int32 y)) (OperationKind.ObjectCreationExpression, Type: ) (Syntax: 'from int y in c2') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: 'from int y in c2') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'from int y in c2') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument) (Syntax: 'from int y in c2') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'from int y in c2') InConversion: null OutConversion: null Initializer: null InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: collectionSelector) (OperationKind.Argument) (Syntax: 'from int z in c3') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int z in c3') ReducedExpression: IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func<, System.Collections.Generic.IEnumerable>) (Syntax: 'c3') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'c3') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'c3') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'c3') ReturnedValue: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'c3') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'c3') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'c3') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: ILocalReferenceExpression: c3 (OperationKind.LocalReferenceExpression, Type: System.Collections.Generic.List) (Syntax: 'c3') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'x + y + z') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func<, System.Int32, System.Int32>) (Syntax: 'x + y + z') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x + y + z') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x + y + z') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x + y + z') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y + z') Left: IBinaryOperatorExpression (BinaryOperationKind.IntegerAdd) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: 'x + y') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: IOperation: (OperationKind.None) (Syntax: 'y') Right: IOperation: (OperationKind.None) (Syntax: 'z') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact] public void RangeVariables02() { var csSource = @" using System; using System.Linq; class Query { public static void Main(string[] args) { var c1 = new int[] {1, 2, 3}; var c2 = new int[] {10, 20, 30}; var c3 = new int[] {100, 200, 300}; var r1 = from int x in c1 from int y in c2 from int z in c3 select x + y + z; Console.WriteLine(r1); } }"; var compilation = CreateStandardCompilation(csSource, new[] { LinqAssemblyRef }); foreach (var dd in compilation.GetDiagnostics()) Console.WriteLine(dd); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Query").Single(); dynamic methodM = (MethodDeclarationSyntax)classC.Members[0]; QueryExpressionSyntax q = methodM.Body.Statements[3].Declaration.Variables[0].Initializer.Value; var info0 = model.GetQueryClauseInfo(q.FromClause); var x = model.GetDeclaredSymbol(q.FromClause); Assert.Equal(SymbolKind.RangeVariable, x.Kind); Assert.Equal("x", x.Name); Assert.Equal("Cast", info0.CastInfo.Symbol.Name); Assert.Equal(MethodKind.ReducedExtension, ((IMethodSymbol)info0.CastInfo.Symbol).MethodKind); Assert.Null(info0.OperationInfo.Symbol); var info1 = model.GetQueryClauseInfo(q.Body.Clauses[0]); var y = model.GetDeclaredSymbol(q.Body.Clauses[0]); Assert.Equal(SymbolKind.RangeVariable, y.Kind); Assert.Equal("y", y.Name); Assert.Equal("Cast", info1.CastInfo.Symbol.Name); Assert.Equal("SelectMany", info1.OperationInfo.Symbol.Name); Assert.Equal(MethodKind.ReducedExtension, ((IMethodSymbol)info1.OperationInfo.Symbol).MethodKind); var info2 = model.GetQueryClauseInfo(q.Body.Clauses[1]); var z = model.GetDeclaredSymbol(q.Body.Clauses[1]); Assert.Equal(SymbolKind.RangeVariable, z.Kind); Assert.Equal("z", z.Name); Assert.Equal("Cast", info2.CastInfo.Symbol.Name); Assert.Equal("SelectMany", info2.OperationInfo.Symbol.Name); var info3 = model.GetSemanticInfoSummary(q.Body.SelectOrGroup); Assert.NotNull(info3); // what about info3's contents ??? var xPyPz = (q.Body.SelectOrGroup as SelectClauseSyntax).Expression as BinaryExpressionSyntax; var xPy = xPyPz.Left as BinaryExpressionSyntax; Assert.Equal(x, model.GetSemanticInfoSummary(xPy.Left).Symbol); Assert.Equal(y, model.GetSemanticInfoSummary(xPy.Right).Symbol); Assert.Equal(z, model.GetSemanticInfoSummary(xPyPz.Right).Symbol); } [Fact] public void TestGetSemanticInfo01() { var csSource = @" using C = List1;" + LINQ + @" class Query { public static void Main(string[] args) { C c1 = new C(1, 2, 3); C c2 = new C(10, 20, 30); C r1 = from int x in c1 from int y in c2 select x + y; Console.WriteLine(r1); } }"; var compilation = CreateStandardCompilation(csSource); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Query").Single(); dynamic methodM = (MethodDeclarationSyntax)classC.Members[0]; QueryExpressionSyntax q = methodM.Body.Statements[2].Declaration.Variables[0].Initializer.Value; var info0 = model.GetQueryClauseInfo(q.FromClause); Assert.Equal("Cast", info0.CastInfo.Symbol.Name); Assert.Null(info0.OperationInfo.Symbol); Assert.Equal("x", model.GetDeclaredSymbol(q.FromClause).Name); var info1 = model.GetQueryClauseInfo(q.Body.Clauses[0]); Assert.Equal("Cast", info1.CastInfo.Symbol.Name); Assert.Equal("SelectMany", info1.OperationInfo.Symbol.Name); Assert.Equal("y", model.GetDeclaredSymbol(q.Body.Clauses[0]).Name); var info2 = model.GetSemanticInfoSummary(q.Body.SelectOrGroup); // what about info2's contents? } [Fact] public void TestGetSemanticInfo02() { var csSource = LINQ + @" class Query { public static void Main(string[] args) { List1 c = new List1(28, 51, 27, 84, 27, 27, 72, 64, 55, 46, 39); var r = from i in c orderby i/10 descending, i%10 select i; Console.WriteLine(r); } }"; var compilation = CreateStandardCompilation(csSource); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Query").Single(); dynamic methodM = (MethodDeclarationSyntax)classC.Members[0]; QueryExpressionSyntax q = methodM.Body.Statements[1].Declaration.Variables[0].Initializer.Value; var info0 = model.GetQueryClauseInfo(q.FromClause); Assert.Null(info0.CastInfo.Symbol); Assert.Null(info0.OperationInfo.Symbol); Assert.Equal("i", model.GetDeclaredSymbol(q.FromClause).Name); var i = model.GetDeclaredSymbol(q.FromClause); var info1 = model.GetQueryClauseInfo(q.Body.Clauses[0]); Assert.Null(info1.CastInfo.Symbol); Assert.Null(info1.OperationInfo.Symbol); Assert.Null(model.GetDeclaredSymbol(q.Body.Clauses[0])); var order = q.Body.Clauses[0] as OrderByClauseSyntax; var oinfo0 = model.GetSemanticInfoSummary(order.Orderings[0]); Assert.Equal("OrderByDescending", oinfo0.Symbol.Name); var oinfo1 = model.GetSemanticInfoSummary(order.Orderings[1]); Assert.Equal("ThenBy", oinfo1.Symbol.Name); } [WorkItem(541774, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541774")] [Fact] public void MultipleFromClauseIdentifierInExprNotInContext() { string source = @" using System.Linq; class Program { static void Main(string[] args) { var q2 = /**/from n1 in nums from n2 in nums select n1/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: ?, IsInvalid) (Syntax: 'from n1 in ... select n1') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select n1') ReducedExpression: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'from n2 in nums') ReducedExpression: IInvocationExpression (? Program.SelectMany()) (OperationKind.InvocationExpression, Type: ?, IsInvalid) (Syntax: 'from n2 in nums') Instance Receiver: null Arguments(3): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'from n1 in nums') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'from n1 in nums') ReducedExpression: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'nums') Children(0) InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'from n2 in nums') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'from n2 in nums') ReducedExpression: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'nums') IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'nums') IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'nums') ReturnedValue: IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'nums') Children(0) InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'n1') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'n1') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'n1') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'n1') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'n1') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0103: The name 'nums' does not exist in the current context // var q2 = /**/from n1 in nums Diagnostic(ErrorCode.ERR_NameNotInContext, "nums").WithArguments("nums").WithLocation(8, 39), // CS0103: The name 'nums' does not exist in the current context // from n2 in nums Diagnostic(ErrorCode.ERR_NameNotInContext, "nums").WithArguments("nums").WithLocation(9, 29) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(541906, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541906")] [Fact] public void NullLiteralFollowingJoinInQuery() { string source = @" using System.Linq; class Program { static void Main(string[] args) { var query = /**/from int i in new int[] { 1 } join null on true equals true select i/**/; //CS1031 } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: ?, IsInvalid) (Syntax: 'from int i ... ue select i') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select i') ReducedExpression: IJoinQueryClause (Clause kind: JoinClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'join null o ... equals true') ReducedExpression: IInvocationExpression (? Program.Join()) (OperationKind.InvocationExpression, Type: ?, IsInvalid) (Syntax: 'join null o ... equals true') Instance Receiver: null Arguments(5): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'from int i ... int[] { 1 }') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from int i ... int[] { 1 }') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from int i ... int[] { 1 }') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'new int[] { 1 }') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable) (Syntax: 'new int[] { 1 }') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: IArrayCreationExpression (Element Type: System.Int32) (OperationKind.ArrayCreationExpression, Type: System.Int32[]) (Syntax: 'new int[] { 1 }') Dimension Sizes(1): ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: 'new int[] { 1 }') Initializer: IArrayInitializer (1 elements) (OperationKind.ArrayInitializer) (Syntax: '{ 1 }') Element Values(1): ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'join null o ... equals true') IInvocationExpression (? Program.Cast()) (OperationKind.InvocationExpression, Type: ?, IsInvalid) (Syntax: 'join null o ... equals true') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'null') IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'null') Children(1): ILiteralExpression (Text: null) (OperationKind.LiteralExpression, Type: null, Constant: null, IsInvalid) (Syntax: 'null') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'true') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'true') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'true') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'true') ReturnedValue: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True) (Syntax: 'true') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'true') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'true') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'true') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'true') ReturnedValue: ILiteralExpression (OperationKind.LiteralExpression, Type: System.Boolean, Constant: True) (Syntax: 'true') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'i') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'i') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'i') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'i') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'i') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS1031: Type expected // var query = /**/from int i in new int[] { 1 } join null on true equals true select i/**/; //CS1031 Diagnostic(ErrorCode.ERR_TypeExpected, "null").WithLocation(8, 66), // CS1001: Identifier expected // var query = /**/from int i in new int[] { 1 } join null on true equals true select i/**/; //CS1031 Diagnostic(ErrorCode.ERR_IdentifierExpected, "null").WithLocation(8, 66), // CS1003: Syntax error, 'in' expected // var query = /**/from int i in new int[] { 1 } join null on true equals true select i/**/; //CS1031 Diagnostic(ErrorCode.ERR_SyntaxError, "null").WithArguments("in", "null").WithLocation(8, 66) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(541779, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541779")] [Fact] public void MultipleFromClauseQueryExpr() { var csSource = @" using System; using System.Linq; class Program { static void Main(string[] args) { var nums = new int[] { 3, 4 }; var q2 = from int n1 in nums from int n2 in nums select n1; string serializer = String.Empty; foreach (var q in q2) { serializer = serializer + q + "" ""; } System.Console.Write(serializer.Trim()); } }"; CompileAndVerify(csSource, additionalRefs: new[] { LinqAssemblyRef }, expectedOutput: "3 3 4 4"); } [WorkItem(541782, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541782")] [Fact] public void FromSelectQueryExprOnArraysWithTypeImplicit() { var csSource = @" using System; using System.Linq; class Program { static void Main(string[] args) { var nums = new int[] { 3, 4 }; var q2 = from n1 in nums select n1; string serializer = String.Empty; foreach (var q in q2) { serializer = serializer + q + "" ""; } System.Console.Write(serializer.Trim()); } }"; CompileAndVerify(csSource, additionalRefs: new[] { LinqAssemblyRef }, expectedOutput: "3 4"); } [WorkItem(541788, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541788")] [Fact] public void JoinClauseTest() { var csSource = @" using System; using System.Linq; class Program { static void Main() { var q2 = from a in Enumerable.Range(1, 13) join b in Enumerable.Range(1, 13) on 4 * a equals b select a; string serializer = String.Empty; foreach (var q in q2) { serializer = serializer + q + "" ""; } System.Console.Write(serializer.Trim()); } }"; CompileAndVerify(csSource, additionalRefs: new[] { LinqAssemblyRef }, expectedOutput: "1 2 3"); } [Fact, WorkItem(17838, "https://github.com/dotnet/roslyn/issues/17838")] public void JoinClause_IOperation() { string source = @" using System; using System.Linq; class Program { static void Main() { var q2 = /**/from a in Enumerable.Range(1, 13) join b in Enumerable.Range(1, 13) on 4 * a equals b select a/**/; string serializer = String.Empty; foreach (var q in q2) { serializer = serializer + q + "" ""; } System.Console.Write(serializer.Trim()); } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from a in E ... select a') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select a') ReducedExpression: IJoinQueryClause (Clause kind: JoinClause) (OperationKind.QueryClause) (Syntax: 'join b in E ... a equals b') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Join(this System.Collections.Generic.IEnumerable outer, System.Collections.Generic.IEnumerable inner, System.Func outerKeySelector, System.Func innerKeySelector, System.Func resultSelector)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'join b in E ... a equals b') Instance Receiver: null Arguments(5): IArgument (ArgumentKind.Explicit, Matching Parameter: outer) (OperationKind.Argument) (Syntax: 'from a in E ... ange(1, 13)') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from a in E ... ange(1, 13)') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Range(System.Int32 start, System.Int32 count)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'Enumerable.Range(1, 13)') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: start) (OperationKind.Argument) (Syntax: '1') ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: count) (OperationKind.Argument) (Syntax: '13') ILiteralExpression (Text: 13) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 13) (Syntax: '13') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: inner) (OperationKind.Argument) (Syntax: 'Enumerable.Range(1, 13)') IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Range(System.Int32 start, System.Int32 count)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'Enumerable.Range(1, 13)') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: start) (OperationKind.Argument) (Syntax: '1') ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: count) (OperationKind.Argument) (Syntax: '13') ILiteralExpression (Text: 13) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 13) (Syntax: '13') InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: outerKeySelector) (OperationKind.Argument) (Syntax: '4 * a') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: '4 * a') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '4 * a') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '4 * a') IReturnStatement (OperationKind.ReturnStatement) (Syntax: '4 * a') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.IntegerMultiply) (OperationKind.BinaryOperatorExpression, Type: System.Int32) (Syntax: '4 * a') Left: ILiteralExpression (Text: 4) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 4) (Syntax: '4') Right: IOperation: (OperationKind.None) (Syntax: 'a') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: innerKeySelector) (OperationKind.Argument) (Syntax: 'b') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'b') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'b') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'b') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'b') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'b') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: resultSelector) (OperationKind.Argument) (Syntax: 'a') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func) (Syntax: 'a') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'a') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'a') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'a') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'a') InConversion: null OutConversion: null "; var expectedDiagnostics = DiagnosticDescription.None; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(541789, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541789")] [WorkItem(9229, "DevDiv_Projects/Roslyn")] [Fact] public void WhereClauseTest() { var csSource = @" using System; using System.Linq; class Program { static void Main() { var nums = new int[] { 1, 2, 3, 4 }; var q2 = from x in nums where (x > 2) select x; string serializer = String.Empty; foreach (var q in q2) { serializer = serializer + q + "" ""; } System.Console.Write(serializer.Trim()); } }"; CompileAndVerify(csSource, additionalRefs: new[] { LinqAssemblyRef }, expectedOutput: "3 4"); } [WorkItem(541942, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541942")] [Fact] public void WhereDefinedInType() { var csSource = @" using System; class Y { public int Where(Func predicate) { return 45; } } class P { static void Main() { var src = new Y(); var query = from x in src where x > 0 select x; Console.Write(query); } }"; CompileAndVerify(csSource, additionalRefs: new[] { LinqAssemblyRef }, expectedOutput: "45"); } [Fact] public void GetInfoForSelectExpression01() { string sourceCode = @" using System; using System.Linq; public class Test2 { public static void Main() { var nums = new int[] { 1, 2, 3, 4 }; var q2 = from x in nums select x; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); SelectClauseSyntax selectClause = (SelectClauseSyntax)tree.GetCompilationUnitRoot().FindToken(sourceCode.IndexOf("select", StringComparison.Ordinal)).Parent; var info = semanticModel.GetSemanticInfoSummary(selectClause.Expression); Assert.Equal(SpecialType.System_Int32, info.Type.SpecialType); Assert.Equal(SymbolKind.RangeVariable, info.Symbol.Kind); var info2 = semanticModel.GetSemanticInfoSummary(selectClause); var m = (MethodSymbol)info2.Symbol; Assert.Equal("Select", m.ReducedFrom.Name); } [Fact] public void GetInfoForSelectExpression02() { string sourceCode = @" using System; using System.Linq; public class Test2 { public static void Main() { var nums = new int[] { 1, 2, 3, 4 }; var q2 = from x in nums select x into w select w; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); SelectClauseSyntax selectClause = (SelectClauseSyntax)tree.GetCompilationUnitRoot().FindToken(sourceCode.IndexOf("select w", StringComparison.Ordinal)).Parent; var info = semanticModel.GetSemanticInfoSummary(selectClause.Expression); Assert.Equal(SpecialType.System_Int32, info.Type.SpecialType); Assert.Equal(SymbolKind.RangeVariable, info.Symbol.Kind); } [Fact] public void GetInfoForSelectExpression03() { string sourceCode = @" using System.Linq; public class Test2 { public static void Main() { var nums = new int[] { 1, 2, 3, 4 }; var q2 = from x in nums select x+1 into w select w+1; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; compilation.VerifyDiagnostics(); var semanticModel = compilation.GetSemanticModel(tree); var e = (IdentifierNameSyntax)tree.GetCompilationUnitRoot().FindToken(sourceCode.IndexOf("x+1", StringComparison.Ordinal)).Parent; var info = semanticModel.GetSemanticInfoSummary(e); Assert.Equal(SpecialType.System_Int32, info.Type.SpecialType); Assert.Equal(SymbolKind.RangeVariable, info.Symbol.Kind); Assert.Equal("x", info.Symbol.Name); e = (IdentifierNameSyntax)tree.GetCompilationUnitRoot().FindToken(sourceCode.IndexOf("w+1", StringComparison.Ordinal)).Parent; info = semanticModel.GetSemanticInfoSummary(e); Assert.Equal(SpecialType.System_Int32, info.Type.SpecialType); Assert.Equal(SymbolKind.RangeVariable, info.Symbol.Kind); Assert.Equal("w", info.Symbol.Name); var e2 = e.Parent as ExpressionSyntax; // w+1 var info2 = semanticModel.GetSemanticInfoSummary(e2); Assert.Equal(SpecialType.System_Int32, info2.Type.SpecialType); Assert.Equal("System.Int32 System.Int32.op_Addition(System.Int32 left, System.Int32 right)", info2.Symbol.ToTestDisplayString()); } [WorkItem(541806, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541806")] [Fact] public void GetDeclaredSymbolForQueryContinuation() { string sourceCode = @" public class Test2 { public static void Main() { var nums = new int[] { 1, 2, 3, 4 }; var q2 = from x in nums select x into w select w; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var queryContinuation = tree.GetRoot().FindToken(sourceCode.IndexOf("into w", StringComparison.Ordinal)).Parent; var symbol = semanticModel.GetDeclaredSymbol(queryContinuation); Assert.NotNull(symbol); Assert.Equal("w", symbol.Name); Assert.Equal(SymbolKind.RangeVariable, symbol.Kind); } [WorkItem(541899, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541899")] [Fact] public void ComputeQueryVariableType() { string sourceCode = @" using System.Linq; public class Test2 { public static void Main() { var nums = new int[] { 1, 2, 3, 4 }; var q2 = from x in nums select 5; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var selectExpression = tree.GetCompilationUnitRoot().FindToken(sourceCode.IndexOf('5')); var info = semanticModel.GetSpeculativeTypeInfo(selectExpression.SpanStart, SyntaxFactory.ParseExpression("x"), SpeculativeBindingOption.BindAsExpression); Assert.Equal(SpecialType.System_Int32, info.Type.SpecialType); } [WorkItem(541893, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541893")] [Fact] public void GetDeclaredSymbolForJoinIntoClause() { string sourceCode = @" using System; using System.Linq; static class Test { static void Main() { var qie = from x3 in new int[] { 0 } join x7 in (new int[] { 0 }) on 5 equals 5 into x8 select x8; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var joinInto = tree.GetRoot().FindToken(sourceCode.IndexOf("into x8", StringComparison.Ordinal)).Parent; var symbol = semanticModel.GetDeclaredSymbol(joinInto); Assert.NotNull(symbol); Assert.Equal("x8", symbol.Name); Assert.Equal(SymbolKind.RangeVariable, symbol.Kind); Assert.Equal("? x8", symbol.ToTestDisplayString()); } [WorkItem(541982, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/541982")] [WorkItem(543494, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543494")] [Fact()] public void GetDeclaredSymbolAddAccessorDeclIncompleteQuery() { string sourceCode = @" using System; using System.Linq; public class QueryExpressionTest { public static void Main() { var expr1 = new[] { 1, 2, 3, 4, 5 }; var query1 = from event in expr1 select event; var query2 = from int } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var unknownAccessorDecls = tree.GetCompilationUnitRoot().DescendantNodes().OfType(); var symbols = unknownAccessorDecls.Select(decl => semanticModel.GetDeclaredSymbol(decl)); Assert.True(symbols.All(s => ReferenceEquals(s, null))); } [WorkItem(542235, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542235")] [Fact] public void TwoFromClauseFollowedBySelectClause() { string sourceCode = @" using System.Linq; class Test { public static void Main() { var q2 = from num1 in new int[] { 4, 5 } from num2 in new int[] { 4, 5 } select num1; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var selectClause = tree.GetCompilationUnitRoot().DescendantNodes().Where(n => n.IsKind(SyntaxKind.SelectClause)).Single() as SelectClauseSyntax; var fromClause1 = tree.GetCompilationUnitRoot().DescendantNodes().Where(n => (n.IsKind(SyntaxKind.FromClause)) && (n.ToString().Contains("num1"))).Single() as FromClauseSyntax; var fromClause2 = tree.GetCompilationUnitRoot().DescendantNodes().Where(n => (n.IsKind(SyntaxKind.FromClause)) && (n.ToString().Contains("num2"))).Single() as FromClauseSyntax; var symbolInfoForSelect = semanticModel.GetSemanticInfoSummary(selectClause); var queryInfoForFrom1 = semanticModel.GetQueryClauseInfo(fromClause1); var queryInfoForFrom2 = semanticModel.GetQueryClauseInfo(fromClause2); Assert.Null(queryInfoForFrom1.CastInfo.Symbol); Assert.Null(queryInfoForFrom1.OperationInfo.Symbol); Assert.Null(queryInfoForFrom2.CastInfo.Symbol); Assert.Equal("SelectMany", queryInfoForFrom2.OperationInfo.Symbol.Name); Assert.Null(symbolInfoForSelect.Symbol); Assert.Empty(symbolInfoForSelect.CandidateSymbols); Assert.Equal(CandidateReason.None, symbolInfoForSelect.CandidateReason); } [WorkItem(528747, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528747")] [Fact] public void SemanticInfoForOrderingClauses() { string sourceCode = @" using System; using System.Linq; public class QueryExpressionTest { public static void Main() { var q1 = from x in new int[] { 4, 5 } orderby x descending, x.ToString() ascending, x descending select x; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); int count = 0; string[] names = { "OrderByDescending", "ThenBy", "ThenByDescending" }; foreach (var ordering in tree.GetCompilationUnitRoot().DescendantNodes().OfType()) { var symbolInfo = model.GetSemanticInfoSummary(ordering); Assert.Equal(names[count++], symbolInfo.Symbol.Name); } Assert.Equal(3, count); } [WorkItem(542266, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542266")] [Fact] public void FromOrderBySelectQueryTranslation() { string sourceCode = @" using System; using System.Collections; using System.Collections.Generic; public interface IOrderedEnumerable : IEnumerable, IEnumerable { } public static class Extensions { public static IOrderedEnumerable OrderBy( this IEnumerable source, Func keySelector) { return null; } public static IEnumerable Select( this IEnumerable source, Func selector) { return null; } } class Program { static void Main(string[] args) { var q1 = from num in new int[] { 4, 5 } orderby num select num; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var selectClause = tree.GetCompilationUnitRoot().DescendantNodes().Where(n => n.IsKind(SyntaxKind.SelectClause)).Single() as SelectClauseSyntax; var symbolInfoForSelect = semanticModel.GetSemanticInfoSummary(selectClause); Assert.Null(symbolInfoForSelect.Symbol); } [WorkItem(528756, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528756")] [Fact] public void FromWhereSelectTranslation() { string sourceCode = @" using System; using System.Collections.Generic; public static class Extensions { public static IEnumerable Where( this IEnumerable source, Func predicate) { return null; } } class Program { static void Main(string[] args) { var q1 = from num in System.Linq.Enumerable.Range(4, 5).Where(n => n > 10) select num; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); semanticModel.GetDiagnostics().Verify( // (21,30): error CS1935: Could not find an implementation of the query pattern for source type 'System.Collections.Generic.IEnumerable'. 'Select' not found. Are you missing a reference to 'System.Core.dll' or a using directive for 'System.Linq'? // var q1 = from num in System.Linq.Enumerable.Range(4, 5).Where(n => n > 10) Diagnostic(ErrorCode.ERR_QueryNoProviderStandard, "System.Linq.Enumerable.Range(4, 5).Where(n => n > 10)").WithArguments("System.Collections.Generic.IEnumerable", "Select")); } [WorkItem(528760, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528760")] [Fact] public void FromJoinSelectTranslation() { string sourceCode = @" using System.Linq; class Program { static void Main(string[] args) { var q1 = from num in new int[] { 4, 5 } join x1 in new int[] { 4, 5 } on num equals x1 select x1 + 5; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var selectClause = tree.GetCompilationUnitRoot().DescendantNodes().Where(n => n.IsKind(SyntaxKind.SelectClause)).Single() as SelectClauseSyntax; var symbolInfoForSelect = semanticModel.GetSemanticInfoSummary(selectClause); Assert.Null(symbolInfoForSelect.Symbol); } [WorkItem(528761, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/528761")] [WorkItem(544585, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544585")] [Fact] public void OrderingSyntaxWithOverloadResolutionFailure() { string sourceCode = @" using System.Linq; class Program { static void Main(string[] args) { int[] numbers = new int[] { 4, 5 }; var q1 = from num in numbers.Single() orderby (x1) => x1.ToString() select num; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics( // (10,30): error CS1936: Could not find an implementation of the query pattern for source type 'int'. 'OrderBy' not found. // var q1 = from num in numbers.Single() Diagnostic(ErrorCode.ERR_QueryNoProvider, "numbers.Single()").WithArguments("int", "OrderBy") ); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var orderingClause = tree.GetCompilationUnitRoot().DescendantNodes().Where(n => n.IsKind(SyntaxKind.AscendingOrdering)).Single() as OrderingSyntax; var symbolInfoForOrdering = semanticModel.GetSemanticInfoSummary(orderingClause); Assert.Null(symbolInfoForOrdering.Symbol); } [WorkItem(542292, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542292")] [Fact] public void EmitIncompleteQueryWithSyntaxErrors() { string sourceCode = @" using System.Linq; class Program { static int Main() { int [] goo = new int [] {1}; var q = from x in goo select x + 1 into z select z.T "; using (var output = new MemoryStream()) { Assert.False(CreateCompilationWithMscorlibAndSystemCore(sourceCode).Emit(output).Success); } } [WorkItem(542294, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542294")] [Fact] public void EmitQueryWithBindErrors() { string sourceCode = @" using System.Linq; class Program { static void Main() { int[] nums = { 0, 1, 2, 3, 4, 5 }; var query = from num in nums let num = 3 // CS1930 select num; } }"; using (var output = new MemoryStream()) { Assert.False(CreateCompilationWithMscorlibAndSystemCore(sourceCode).Emit(output).Success); } } [WorkItem(542372, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542372")] [Fact] public void BindToIncompleteSelectManyDecl() { string sourceCode = @" class P { static C M2(X x) { return new C(x); } static void Main() { C e1 = new C(1); var q = from x1 in M2(x1) from x2 in e1 select x1; } } class C { public C SelectMany"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var diags = semanticModel.GetDiagnostics(); Assert.NotEmpty(diags); } [WorkItem(542419, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542419")] [Fact] public void BindIdentifierInWhereErrorTolerance() { string sourceCode = @" using System; using System.Collections.Generic; using System.Linq; class Program { static void Main(string[] args) { var r = args.Where(b => b < > ); var q = from a in args where a <> } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var diags = semanticModel.GetDiagnostics(); Assert.NotEmpty(diags); } [WorkItem(542460, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542460")] [Fact] public void QueryWithMultipleParseErrorsAndScriptParseOption() { string sourceCode = @" using System; using System.Linq; public class QueryExpressionTest { public static void Main() { var expr1 = new int[] { 1, 2, 3, 4, 5 }; var query2 = from int namespace in expr1 select namespace; var query25 = from i in expr1 let namespace = expr1 select i; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode, parseOptions: TestOptions.Script); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var queryExpr = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Where(x => x.ToFullString() == "from i in expr1 let ").Single(); var symbolInfo = semanticModel.GetSemanticInfoSummary(queryExpr); Assert.Null(symbolInfo.Symbol); } [WorkItem(542496, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542496")] [Fact] public void QueryExpressionInFieldInitReferencingAnotherFieldWithScriptParseOption() { string sourceCode = @" using System.Linq; using System.Collections; class P { double one = 1; public IEnumerable e = from x in new int[] { 1, 2, 3 } select x + one; }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode, parseOptions: TestOptions.Script); var tree = compilation.SyntaxTrees[0]; var semanticModel = compilation.GetSemanticModel(tree); var queryExpr = tree.GetCompilationUnitRoot().DescendantNodes().OfType().Single(); var symbolInfo = semanticModel.GetSemanticInfoSummary(queryExpr); Assert.Null(symbolInfo.Symbol); } [WorkItem(542559, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542559")] [Fact] public void StaticTypeInFromClause() { string source = @" using System; using System.Linq; class C { static void Main() { var q2 = string.Empty.Cast().Select(x => x); var q1 = /**/from GC x in string.Empty select x/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: ?, IsInvalid) (Syntax: 'from GC x i ... ty select x') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select x') ReducedExpression: IInvocationExpression (? C.Select()) (OperationKind.InvocationExpression, Type: ?) (Syntax: 'select x') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'from GC x i ... tring.Empty') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'from GC x i ... tring.Empty') ReducedExpression: IInvocationExpression (System.Collections.Generic.IEnumerable System.Linq.Enumerable.Cast(this System.Collections.IEnumerable source)) (OperationKind.InvocationExpression, Type: System.Collections.Generic.IEnumerable, IsInvalid) (Syntax: 'from GC x i ... tring.Empty') Instance Receiver: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'string.Empty') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.IEnumerable, IsInvalid) (Syntax: 'string.Empty') Conversion: CommonConversion (Exists: True, IsIdentity: False, IsNumeric: False, IsReference: True, IsUserDefined: False) (MethodSymbol: null) Operand: IFieldReferenceExpression: System.String System.String.Empty (Static) (OperationKind.FieldReferenceExpression, Type: System.String, IsInvalid) (Syntax: 'string.Empty') Instance Receiver: null InConversion: null OutConversion: null InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'x') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'x') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0718: 'GC': static types cannot be used as type arguments // var q2 = string.Empty.Cast().Select(x => x); Diagnostic(ErrorCode.ERR_GenericArgIsStaticClass, "string.Empty.Cast").WithArguments("System.GC").WithLocation(9, 18), // CS0718: 'GC': static types cannot be used as type arguments // var q1 = /**/from GC x in string.Empty select x/**/; Diagnostic(ErrorCode.ERR_GenericArgIsStaticClass, "from GC x in string.Empty").WithArguments("System.GC").WithLocation(10, 28) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(542560, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542560")] [Fact] public void MethodGroupInFromClause() { string source = @" using System; using System.Linq; class Program { static void Main() { var q1 = /**/from y in Main select y/**/; var q2 = Main.Select(y => y); } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: ?, IsInvalid) (Syntax: 'from y in Main select y') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select y') ReducedExpression: IInvocationExpression (? Program.Select()) (OperationKind.InvocationExpression, Type: ?) (Syntax: 'select y') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'from y in Main') IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'from y in Main') Children(1): IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'from y in Main') ReducedExpression: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'Main') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'y') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'y') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'y') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'y') ReturnedValue: IOperation: (OperationKind.None) (Syntax: 'y') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0119: 'Program.Main()' is a method, which is not valid in the given context // var q1 = /**/from y in Main select y/**/; Diagnostic(ErrorCode.ERR_BadSKunknown, "Main").WithArguments("Program.Main()", "method").WithLocation(9, 38), // CS0119: 'Program.Main()' is a method, which is not valid in the given context // var q2 = Main.Select(y => y); Diagnostic(ErrorCode.ERR_BadSKunknown, "Main").WithArguments("Program.Main()", "method").WithLocation(10, 18) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(542558, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542558")] [Fact] public void SelectFromType01() { string sourceCode = @"using System; using System.Collections.Generic; class C { static void Main() { var q = from x in C select x; } static IEnumerable Select(Func f) { return null; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "C").Single(); dynamic main = (MethodDeclarationSyntax)classC.Members[0]; QueryExpressionSyntax q = main.Body.Statements[0].Declaration.Variables[0].Initializer.Value; var info0 = model.GetQueryClauseInfo(q.FromClause); var x = model.GetDeclaredSymbol(q.FromClause); Assert.Equal(SymbolKind.RangeVariable, x.Kind); Assert.Equal("x", x.Name); Assert.Equal(null, info0.CastInfo.Symbol); Assert.Null(info0.OperationInfo.Symbol); var infoSelect = model.GetSemanticInfoSummary(q.Body.SelectOrGroup); Assert.Equal("Select", infoSelect.Symbol.Name); } [WorkItem(542558, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542558")] [Fact] public void SelectFromType02() { string sourceCode = @"using System; using System.Collections.Generic; class C { static void Main() { var q = from x in C select x; } static Func, IEnumerable> Select = null; }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "C").Single(); dynamic main = (MethodDeclarationSyntax)classC.Members[0]; QueryExpressionSyntax q = main.Body.Statements[0].Declaration.Variables[0].Initializer.Value; var info0 = model.GetQueryClauseInfo(q.FromClause); var x = model.GetDeclaredSymbol(q.FromClause); Assert.Equal(SymbolKind.RangeVariable, x.Kind); Assert.Equal("x", x.Name); Assert.Equal(null, info0.CastInfo.Symbol); Assert.Null(info0.OperationInfo.Symbol); var infoSelect = model.GetSemanticInfoSummary(q.Body.SelectOrGroup); Assert.Equal("Select", infoSelect.Symbol.Name); } [WorkItem(542624, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542624")] [Fact] public void QueryColorColor() { string sourceCode = @" using System; using System.Collections.Generic; class Color { public static IEnumerable Select(Func f) { return null; } } class Flavor { public IEnumerable Select(Func f) { return null; } } class Program { Color Color; static Flavor Flavor; static void Main() { var q1 = from x in Color select x; var q2 = from x in Flavor select x; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics( // (17,11): warning CS0169: The field 'Program.Color' is never used // Color Color; Diagnostic(ErrorCode.WRN_UnreferencedField, "Color").WithArguments("Program.Color"), // (18,19): warning CS0649: Field 'Program.Flavor' is never assigned to, and will always have its default value null // static Flavor Flavor; Diagnostic(ErrorCode.WRN_UnassignedInternalField, "Flavor").WithArguments("Program.Flavor", "null") ); } [WorkItem(542704, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542704")] [Fact] public void QueryOnSourceWithGroupByMethod() { string source = @" delegate T Func(A a); class Y { public U u; public Y(U u) { this.u = u; } public string GroupBy(Func keySelector) { return null; } } class Test { static int Main() { Y src = new Y(2); string q1 = src.GroupBy(x => x.GetType().Name); // ok string q2 = from x in src group x by x.GetType().Name; // Roslyn CS1501 return 0; } } "; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); compilation.VerifyDiagnostics(); } [Fact] public void RangeTypeAlreadySpecified() { string source = @" using System.Linq; using System.Collections; static class Test { public static void Main2() { var list = new CastableToArrayList(); var q = /**/from int x in list select x + 1/**/; } } class CastableToArrayList { public ArrayList Cast() { return null; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: ?, IsInvalid) (Syntax: 'from int x ... elect x + 1') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select x + 1') ReducedExpression: IInvocationExpression (? Test.Select()) (OperationKind.InvocationExpression, Type: ?) (Syntax: 'select x + 1') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'from int x in list') IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'from int x in list') ReducedExpression: IInvocationExpression ( System.Collections.ArrayList CastableToArrayList.Cast()) (OperationKind.InvocationExpression, Type: System.Collections.ArrayList, IsInvalid) (Syntax: 'from int x in list') Instance Receiver: ILocalReferenceExpression: list (OperationKind.LocalReferenceExpression, Type: CastableToArrayList, IsInvalid) (Syntax: 'list') Arguments(0) InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'x + 1') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x + 1') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x + 1') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x + 1') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.Invalid) (OperationKind.BinaryOperatorExpression, Type: ?) (Syntax: 'x + 1') Left: IOperation: (OperationKind.None) (Syntax: 'x') Right: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS1936: Could not find an implementation of the query pattern for source type 'ArrayList'. 'Select' not found. // var q = /**/from int x in list Diagnostic(ErrorCode.ERR_QueryNoProvider, "list").WithArguments("System.Collections.ArrayList", "Select").WithLocation(10, 41) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(11414, "DevDiv_Projects/Roslyn")] [Fact] public void InvalidQueryWithAnonTypesAndKeywords() { string source = @" public class QueryExpressionTest { public static void Main() { var query7 = from i in expr1 join const in expr2 on i equals const select new { i, const }; var query8 = from int i in expr1 select new { i, const }; } } "; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); Assert.NotEmpty(compilation.GetDiagnostics()); } [WorkItem(543787, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543787")] [ClrOnlyFact] public void GetSymbolInfoOfSelectNodeWhenTypeOfRangeVariableIsErrorType() { string source = @" using System.Linq; class Test { static void V() { } public static int Main() { var e1 = from i in V() select i; } } "; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); var tree = compilation.SyntaxTrees.First(); var index = source.IndexOf("select i", StringComparison.Ordinal); var selectNode = tree.GetCompilationUnitRoot().FindToken(index).Parent as SelectClauseSyntax; var model = compilation.GetSemanticModel(tree); var symbolInfo = model.GetSymbolInfo(selectNode); Assert.NotNull(symbolInfo); Assert.Null(symbolInfo.Symbol); // there is no select method to call because the receiver is bad var typeInfo = model.GetTypeInfo(selectNode); Assert.Equal(SymbolKind.ErrorType, typeInfo.Type.Kind); } [WorkItem(543790, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543790")] [Fact] public void GetQueryClauseInfoForQueryWithSyntaxErrors() { string source = @" using System.Linq; class Test { public static void Main () { var query8 = from int i in expr1 join int delegate in expr2 on i equals delegate select new { i, delegate }; } } "; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); var tree = compilation.SyntaxTrees.First(); var index = source.IndexOf("join int delegate in expr2 on i equals delegate", StringComparison.Ordinal); var joinNode = tree.GetCompilationUnitRoot().FindToken(index).Parent as JoinClauseSyntax; var model = compilation.GetSemanticModel(tree); var queryInfo = model.GetQueryClauseInfo(joinNode); Assert.NotNull(queryInfo); } [WorkItem(545797, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545797")] [Fact] public void QueryOnNull() { string source = @" using System; static class C { static void Main() { var q = /**/from x in null select x/**/; } static object Select(this object x, Func y) { return null; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Object, IsInvalid) (Syntax: 'from x in null select x') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'select x') ReducedExpression: IInvocationExpression (System.Object C.Select(this System.Object x, System.Func y)) (OperationKind.InvocationExpression, Type: System.Object, IsInvalid) (Syntax: 'select x') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'from x in null') IInvalidExpression (OperationKind.InvalidExpression, Type: ?) (Syntax: 'from x in null') Children(1): IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from x in null') ReducedExpression: ILiteralExpression (Text: null) (OperationKind.LiteralExpression, Type: null, Constant: null) (Syntax: 'null') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'x') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'x') IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'x') IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'x') ReturnedValue: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'x') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0186: Use of null is not valid in this context // var q = /**/from x in null select x/**/; Diagnostic(ErrorCode.ERR_NullNotValid, "select x").WithLocation(7, 42) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(545797, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545797")] [Fact] public void QueryOnLambda() { string source = @" using System; static class C { static void Main() { var q = /**/from x in y => y select x/**/; } static object Select(this object x, Func y) { return null; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Object, IsInvalid) (Syntax: 'from x in y ... y select x') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'select x') ReducedExpression: IInvocationExpression (System.Object C.Select(this System.Object x, System.Func y)) (OperationKind.InvocationExpression, Type: System.Object, IsInvalid) (Syntax: 'select x') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: 'from x in y => y') IInvalidExpression (OperationKind.InvalidExpression, Type: ?) (Syntax: 'from x in y => y') Children(1): IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from x in y => y') ReducedExpression: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'y => y') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'y') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'y') ReturnedValue: IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: ?) (Syntax: 'y') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'x') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'x') IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'x') IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'x') ReturnedValue: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'x') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS1936: Could not find an implementation of the query pattern for source type 'anonymous method'. 'Select' not found. // var q = /**/from x in y => y select x/**/; Diagnostic(ErrorCode.ERR_QueryNoProvider, "select x").WithArguments("anonymous method", "Select").WithLocation(7, 44) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [WorkItem(545444, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/545444")] [Fact] public void RefOmittedOnComCall() { string source = @"using System; using System.Linq.Expressions; using System.Runtime.InteropServices; [ComImport] [Guid(""A88A175D-2448-447A-B786-64682CBEF156"")] public interface IRef1 { int M(ref int x, int y); } public class Ref1Impl : IRef1 { public int M(ref int x, int y) { return x + y; } } class Test { public static void Main() { IRef1 ref1 = new Ref1Impl(); Expression> F = (x, y) => ref1.M(x, y); } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); compilation.VerifyDiagnostics( // (22,54): error CS2037: An expression tree lambda may not contain a COM call with ref omitted on arguments // Expression> F = (x, y) => ref1.M(x, y); Diagnostic(ErrorCode.ERR_ComRefCallInExpressionTree, "ref1.M(x, y)") ); } [Fact, WorkItem(5728, "https://github.com/dotnet/roslyn/issues/5728")] public void RefOmittedOnComCallErr() { string source = @" using System; using System.Linq.Expressions; using System.Runtime.InteropServices; [ComImport] [Guid(""A88A175D-2448-447A-B786-64682CBEF156"")] public interface IRef1 { long M(uint y, ref int x, int z); long M(uint y, ref int x, int z, int q); } public class Ref1Impl : IRef1 { public long M(uint y, ref int x, int z) { return x + y; } public long M(uint y, ref int x, int z, int q) { return x + y; } } class Test1 { static void Test(Expression> e) { } static void Test(Expression> e) { } public static void Main() { Test(ref1 => ref1.M(1, )); } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); compilation.VerifyDiagnostics( // (34,32): error CS1525: Invalid expression term ')' // Test(ref1 => ref1.M(1, )); Diagnostic(ErrorCode.ERR_InvalidExprTerm, ")").WithArguments(")").WithLocation(34, 32) ); } [WorkItem(529350, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/529350")] [Fact] public void BindLambdaBodyWhenError() { string source = @"using System.Linq; class A { static void Main() { } static void M(System.Reflection.Assembly[] a) { var q2 = a.SelectMany(assem2 => assem2.UNDEFINED, (assem2, t) => t); var q1 = from assem1 in a from t in assem1.UNDEFINED select t; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(source); compilation.VerifyDiagnostics( // (10,48): error CS1061: 'System.Reflection.Assembly' does not contain a definition for 'UNDEFINED' and no extension method 'UNDEFINED' accepting a first argument of type 'System.Reflection.Assembly' could be found (are you missing a using directive or an assembly reference?) // var q2 = a.SelectMany(assem2 => assem2.UNDEFINED, (assem2, t) => t); Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "UNDEFINED").WithArguments("System.Reflection.Assembly", "UNDEFINED"), // (13,35): error CS1061: 'System.Reflection.Assembly' does not contain a definition for 'UNDEFINED' and no extension method 'UNDEFINED' accepting a first argument of type 'System.Reflection.Assembly' could be found (are you missing a using directive or an assembly reference?) // from t in assem1.UNDEFINED Diagnostic(ErrorCode.ERR_NoSuchMemberOrExtension, "UNDEFINED").WithArguments("System.Reflection.Assembly", "UNDEFINED") ); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var assem2 = tree.GetCompilationUnitRoot().DescendantNodes(n => n.ToString().Contains("assem2")) .Where(e => e.ToString() == "assem2") .OfType() .Single(); var typeInfo2 = model.GetTypeInfo(assem2); Assert.NotEqual(TypeKind.Error, typeInfo2.Type.TypeKind); Assert.Equal("Assembly", typeInfo2.Type.Name); var assem1 = tree.GetCompilationUnitRoot().DescendantNodes(n => n.ToString().Contains("assem1")) .Where(e => e.ToString() == "assem1") .OfType() .Single(); var typeInfo1 = model.GetTypeInfo(assem1); Assert.NotEqual(TypeKind.Error, typeInfo1.Type.TypeKind); Assert.Equal("Assembly", typeInfo1.Type.Name); } [Fact] public void TestSpeculativeSemanticModel_GetQueryClauseInfo() { var csSource = @" using C = List1;" + LINQ + @" class Query { public static void Main(string[] args) { C c1 = new C(1, 2, 3); C c2 = new C(10, 20, 30); } }"; var speculatedSource = @" C r1 = from int x in c1 from int y in c2 select x + y; "; var queryStatement = (LocalDeclarationStatementSyntax)SyntaxFactory.ParseStatement(speculatedSource); var compilation = CreateStandardCompilation(csSource); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Query").Single(); var methodM = (MethodDeclarationSyntax)classC.Members[0]; SemanticModel speculativeModel; bool success = model.TryGetSpeculativeSemanticModel(methodM.Body.Statements[1].Span.End, queryStatement, out speculativeModel); Assert.True(success); var q = (QueryExpressionSyntax)queryStatement.Declaration.Variables[0].Initializer.Value; var info0 = speculativeModel.GetQueryClauseInfo(q.FromClause); Assert.Equal("Cast", info0.CastInfo.Symbol.Name); Assert.Null(info0.OperationInfo.Symbol); Assert.Equal("x", speculativeModel.GetDeclaredSymbol(q.FromClause).Name); var info1 = speculativeModel.GetQueryClauseInfo(q.Body.Clauses[0]); Assert.Equal("Cast", info1.CastInfo.Symbol.Name); Assert.Equal("SelectMany", info1.OperationInfo.Symbol.Name); Assert.Equal("y", speculativeModel.GetDeclaredSymbol(q.Body.Clauses[0]).Name); } [Fact] public void TestSpeculativeSemanticModel_GetSemanticInfoForSelectClause() { var csSource = @" using C = List1;" + LINQ + @" class Query { public static void Main(string[] args) { C c1 = new C(1, 2, 3); C c2 = new C(10, 20, 30); } }"; var speculatedSource = @" C r1 = from int x in c1 select x; "; var queryStatement = (LocalDeclarationStatementSyntax)SyntaxFactory.ParseStatement(speculatedSource); var compilation = CreateStandardCompilation(csSource); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Query").Single(); var methodM = (MethodDeclarationSyntax)classC.Members[0]; SemanticModel speculativeModel; bool success = model.TryGetSpeculativeSemanticModel(methodM.Body.Statements[1].Span.End, queryStatement, out speculativeModel); Assert.True(success); var q = (QueryExpressionSyntax)queryStatement.Declaration.Variables[0].Initializer.Value; var x = speculativeModel.GetDeclaredSymbol(q.FromClause); Assert.Equal(SymbolKind.RangeVariable, x.Kind); Assert.Equal("x", x.Name); var selectExpression = (q.Body.SelectOrGroup as SelectClauseSyntax).Expression; Assert.Equal(x, speculativeModel.GetSemanticInfoSummary(selectExpression).Symbol); var selectClauseSymbolInfo = speculativeModel.GetSymbolInfo(q.Body.SelectOrGroup); Assert.NotNull(selectClauseSymbolInfo.Symbol); Assert.Equal("Select", selectClauseSymbolInfo.Symbol.Name); var selectClauseTypeInfo = speculativeModel.GetTypeInfo(q.Body.SelectOrGroup); Assert.NotNull(selectClauseTypeInfo.Type); Assert.Equal("List1", selectClauseTypeInfo.Type.Name); } [Fact] public void TestSpeculativeSemanticModel_GetDeclaredSymbolForJoinIntoClause() { string sourceCode = @" public class Test { public static void Main() { } }"; var speculatedSource = @" var qie = from x3 in new int[] { 0 } join x7 in (new int[] { 1 }) on 5 equals 5 into x8 select x8; "; var queryStatement = SyntaxFactory.ParseStatement(speculatedSource); var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Test").Single(); var methodM = (MethodDeclarationSyntax)classC.Members[0]; SemanticModel speculativeModel; bool success = model.TryGetSpeculativeSemanticModel(methodM.Body.SpanStart, queryStatement, out speculativeModel); var queryExpression = (QueryExpressionSyntax)((LocalDeclarationStatementSyntax)queryStatement).Declaration.Variables[0].Initializer.Value; JoinIntoClauseSyntax joinInto = ((JoinClauseSyntax)queryExpression.Body.Clauses[0]).Into; var symbol = speculativeModel.GetDeclaredSymbol(joinInto); Assert.NotNull(symbol); Assert.Equal("x8", symbol.Name); Assert.Equal(SymbolKind.RangeVariable, symbol.Kind); Assert.Equal("? x8", symbol.ToTestDisplayString()); } [Fact] public void TestSpeculativeSemanticModel_GetDeclaredSymbolForQueryContinuation() { string sourceCode = @" public class Test2 { public static void Main() { var nums = new int[] { 1, 2, 3, 4 }; } }"; var speculatedSource = @" var q2 = from x in nums select x into w select w; "; var queryStatement = SyntaxFactory.ParseStatement(speculatedSource); var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics(); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "Test2").Single(); var methodM = (MethodDeclarationSyntax)classC.Members[0]; SemanticModel speculativeModel; bool success = model.TryGetSpeculativeSemanticModel(methodM.Body.Statements[0].Span.End, queryStatement, out speculativeModel); Assert.True(success); var queryExpression = (QueryExpressionSyntax)((LocalDeclarationStatementSyntax)queryStatement).Declaration.Variables[0].Initializer.Value; var queryContinuation = queryExpression.Body.Continuation; var symbol = speculativeModel.GetDeclaredSymbol(queryContinuation); Assert.NotNull(symbol); Assert.Equal("w", symbol.Name); Assert.Equal(SymbolKind.RangeVariable, symbol.Kind); } [Fact] public void TestSpeculativeSemanticModel_GetSymbolInfoForOrderingClauses() { string sourceCode = @" using System.Linq; // Needed for speculative code. public class QueryExpressionTest { public static void Main() { } }"; var speculatedSource = @" var q1 = from x in new int[] { 4, 5 } orderby x descending, x.ToString() ascending, x descending select x; "; var queryStatement = SyntaxFactory.ParseStatement(speculatedSource); var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics( // (2,1): info CS8019: Unnecessary using directive. // using System.Linq; // Needed for speculative code. Diagnostic(ErrorCode.HDN_UnusedUsingDirective, "using System.Linq;")); var tree = compilation.SyntaxTrees[0]; var model = compilation.GetSemanticModel(tree); var classC = tree.GetCompilationUnitRoot().ChildNodes().OfType().Where(t => t.Identifier.ValueText == "QueryExpressionTest").Single(); var methodM = (MethodDeclarationSyntax)classC.Members[0]; SemanticModel speculativeModel; bool success = model.TryGetSpeculativeSemanticModel(methodM.Body.SpanStart, queryStatement, out speculativeModel); Assert.True(success); int count = 0; string[] names = { "OrderByDescending", "ThenBy", "ThenByDescending" }; foreach (var ordering in queryStatement.DescendantNodes().OfType()) { var symbolInfo = speculativeModel.GetSemanticInfoSummary(ordering); Assert.Equal(names[count++], symbolInfo.Symbol.Name); } Assert.Equal(3, count); } [Fact] public void BrokenQueryPattern() { string source = @" using System; class Q { public Q SelectMany(Func f1, Func f2) { return null; } public Q Select(Func f1) { return null; } //public Q Where(Func f1) { return null; } public X Where(Func f1) { return null; } } class X { public X Select(Func f1) { return null; } } class Program { static void Main(string[] args) { Q q = null; var r = /**/from x in q from y in q where x.ToString() == y.ToString() select x.ToString()/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: X, IsInvalid) (Syntax: 'from x in q ... .ToString()') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'select x.ToString()') ReducedExpression: IInvocationExpression ( X X.Select(System.Func f1)) (OperationKind.InvocationExpression, Type: X, IsInvalid) (Syntax: 'select x.ToString()') Instance Receiver: IWhereQueryClause (Clause kind: WhereClause) (OperationKind.QueryClause) (Syntax: 'where x.ToS ... .ToString()') ReducedExpression: IInvocationExpression ( X Q< y>>.Where(System.Func< y>, System.Boolean> f1)) (OperationKind.InvocationExpression, Type: X) (Syntax: 'where x.ToS ... .ToString()') Instance Receiver: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from y in q') ReducedExpression: IInvocationExpression ( Q< y>> Q.SelectMany, y>>(System.Func> f1, System.Func, y>> f2)) (OperationKind.InvocationExpression, Type: Q< y>>) (Syntax: 'from y in q') Instance Receiver: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from x in q') ReducedExpression: ILocalReferenceExpression: q (OperationKind.LocalReferenceExpression, Type: Q) (Syntax: 'q') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: f1) (OperationKind.Argument) (Syntax: 'q') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>) (Syntax: 'q') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'q') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'q') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'q') ReturnedValue: ILocalReferenceExpression: q (OperationKind.LocalReferenceExpression, Type: Q) (Syntax: 'q') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: f2) (OperationKind.Argument) (Syntax: 'from y in q') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func, y>>) (Syntax: 'from y in q') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'from y in q') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'from y in q') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'from y in q') ReturnedValue: IObjectCreationExpression (Constructor: y>..ctor(System.Int32 x, Q y)) (OperationKind.ObjectCreationExpression, Type: y>) (Syntax: 'from y in q') Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: x) (OperationKind.Argument) (Syntax: 'from y in q') IParameterReferenceExpression: x (OperationKind.ParameterReferenceExpression, Type: System.Int32) (Syntax: 'from y in q') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: y) (OperationKind.Argument) (Syntax: 'from y in q') IParameterReferenceExpression: y (OperationKind.ParameterReferenceExpression, Type: Q) (Syntax: 'from y in q') InConversion: null OutConversion: null Initializer: null InConversion: null OutConversion: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: f1) (OperationKind.Argument) (Syntax: 'x.ToString( ... .ToString()') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func< y>, System.Boolean>) (Syntax: 'x.ToString( ... .ToString()') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: 'x.ToString( ... .ToString()') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: 'x.ToString( ... .ToString()') IReturnStatement (OperationKind.ReturnStatement) (Syntax: 'x.ToString( ... .ToString()') ReturnedValue: IBinaryOperatorExpression (BinaryOperationKind.StringEquals) (OperationKind.BinaryOperatorExpression, Type: System.Boolean) (Syntax: 'x.ToString( ... .ToString()') Left: IInvocationExpression (virtual System.String System.Int32.ToString()) (OperationKind.InvocationExpression, Type: System.String) (Syntax: 'x.ToString()') Instance Receiver: IOperation: (OperationKind.None) (Syntax: 'x') Arguments(0) Right: IInvocationExpression (virtual System.String System.Object.ToString()) (OperationKind.InvocationExpression, Type: System.String) (Syntax: 'y.ToString()') Instance Receiver: IOperation: (OperationKind.None) (Syntax: 'y') Arguments(0) InConversion: null OutConversion: null Arguments(1): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'x.ToString()') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'x.ToString()') IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: 'x.ToString()') IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: 'x.ToString()') ReturnedValue: IInvocationExpression ( ? Program.()) (OperationKind.InvocationExpression, Type: ?, IsInvalid) (Syntax: 'x.ToString()') Instance Receiver: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'x.ToString') Arguments(0) InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS8016: Transparent identifier member access failed for field 'x' of 'int'. Does the data being queried implement the query pattern? // select x.ToString()/**/; Diagnostic(ErrorCode.ERR_UnsupportedTransparentIdentifierAccess, "x").WithArguments("x", "int").WithLocation(27, 20) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact] [WorkItem(204561, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=204561&_a=edit")] public void Bug204561_01() { string sourceCode = @" class C { public static void Main() { var x01 = from a in Test select a + 1; } } public class Test { } public static class TestExtensions { public static Test Select(this Test x, System.Func selector) { return null; } } "; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics( // (6,34): error CS1936: Could not find an implementation of the query pattern for source type 'Test'. 'Select' not found. // var x01 = from a in Test select a + 1; Diagnostic(ErrorCode.ERR_QueryNoProvider, "select a + 1").WithArguments("Test", "Select").WithLocation(6, 34) ); } [Fact] [WorkItem(204561, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=204561&_a=edit")] public void Bug204561_02() { string sourceCode = @" class C { public static void Main() { var y02 = from a in Test select a + 1; var x02 = from a in Test where a > 0 select a + 1; } } class Test { public static Test Select(System.Func selector) { return null; } } static class TestExtensions { public static Test Where(this Test x, System.Func filter) { return null; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics( // (7,34): error CS1936: Could not find an implementation of the query pattern for source type 'Test'. 'Where' not found. // var x02 = from a in Test where a > 0 select a + 1; Diagnostic(ErrorCode.ERR_QueryNoProvider, "where a > 0").WithArguments("Test", "Where").WithLocation(7, 34), // (7,46): error CS0176: Member 'Test.Select(Func)' cannot be accessed with an instance reference; qualify it with a type name instead // var x02 = from a in Test where a > 0 select a + 1; Diagnostic(ErrorCode.ERR_ObjectProhibited, "select a + 1").WithArguments("Test.Select(System.Func)").WithLocation(7, 46) ); } [Fact] [WorkItem(204561, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=204561&_a=edit")] public void Bug204561_03() { string sourceCode = @" class C { public static void Main() { var y03 = from a in Test select a + 1; var x03 = from a in Test where a > 0 select a + 1; } } class Test { } static class TestExtensions { public static Test Select(this Test x, System.Func selector) { return null; } public static Test Where(this Test x, System.Func filter) { return null; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode); compilation.VerifyDiagnostics( // (6,34): error CS1936: Could not find an implementation of the query pattern for source type 'Test'. 'Select' not found. // var y03 = from a in Test select a + 1; Diagnostic(ErrorCode.ERR_QueryNoProvider, "select a + 1").WithArguments("Test", "Select").WithLocation(6, 34), // (7,34): error CS1936: Could not find an implementation of the query pattern for source type 'Test'. 'Where' not found. // var x03 = from a in Test where a > 0 select a + 1; Diagnostic(ErrorCode.ERR_QueryNoProvider, "where a > 0").WithArguments("Test", "Where").WithLocation(7, 34) ); } [Fact] [WorkItem(204561, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=204561&_a=edit")] public void Bug204561_04() { string sourceCode = @" class C { public static void Main() { var x04 = from a in Test select a + 1; } } class Test { public static Test Select(System.Func selector) { System.Console.WriteLine(""Select""); return null; } }"; var compilation = CreateCompilationWithMscorlibAndSystemCore(sourceCode, options: TestOptions.DebugExe); CompileAndVerify(compilation, expectedOutput: "Select"); } [WorkItem(15910, "https://github.com/dotnet/roslyn/issues/15910")] [Fact] public void ExpressionVariablesInQueryClause_01() { var csSource = @" using System.Linq; class Program { public static void Main(string[] args) { var a = new[] { 1, 2, 3, 4 }; var za = from x in M(a, out var q1) select x; // ok var zc = from x in a from y in M(a, out var z) select x; // error 1 var zd = from x in a from int y in M(a, out var z) select x; // error 2 var ze = from x in a from y in M(a, out var z) where true select x; // error 3 var zf = from x in a from int y in M(a, out var z) where true select x; // error 4 var zg = from x in a let y = M(a, out var z) select x; // error 5 var zh = from x in a where M(x, out var z) == 1 select x; // error 6 var zi = from x in a join y in M(a, out var q2) on x equals y select x; // ok var zj = from x in a join y in a on M(x, out var z) equals y select x; // error 7 var zk = from x in a join y in a on x equals M(y, out var z) select x; // error 8 var zl = from x in a orderby M(x, out var z) select x; // error 9 var zm = from x in a orderby x, M(x, out var z) select x; // error 10 var zn = from x in a group M(x, out var z) by x; // error 11 var zo = from x in a group x by M(x, out var z); // error 12 } public static T M(T x, out T z) => z = x; }"; CreateCompilationWithMscorlibAndSystemCore(csSource).VerifyDiagnostics( // (10,53): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zc = from x in a from y in M(a, out var z) select x; // error 1 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(10, 53), // (11,57): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zd = from x in a from int y in M(a, out var z) select x; // error 2 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(11, 57), // (12,53): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var ze = from x in a from y in M(a, out var z) where true select x; // error 3 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(12, 53), // (13,57): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zf = from x in a from int y in M(a, out var z) where true select x; // error 4 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(13, 57), // (14,51): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zg = from x in a let y = M(a, out var z) select x; // error 5 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(14, 51), // (15,49): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zh = from x in a where M(x, out var z) == 1 select x; // error 6 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(15, 49), // (17,58): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zj = from x in a join y in a on M(x, out var z) equals y select x; // error 7 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(17, 58), // (18,67): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zk = from x in a join y in a on x equals M(y, out var z) select x; // error 8 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(18, 67), // (19,51): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zl = from x in a orderby M(x, out var z) select x; // error 9 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(19, 51), // (20,54): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zm = from x in a orderby x, M(x, out var z) select x; // error 10 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(20, 54), // (21,49): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zn = from x in a group M(x, out var z) by x; // error 11 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(21, 49), // (22,54): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zo = from x in a group x by M(x, out var z); // error 12 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(22, 54) ); } [WorkItem(15910, "https://github.com/dotnet/roslyn/issues/15910")] [Fact] public void ExpressionVariablesInQueryClause_02() { var csSource = @" using System.Linq; class Program { public static void Main(string[] args) { var a = new[] { 1, 2, 3, 4 }; var za = from x in M(a, a is var q1) select x; // ok var zc = from x in a from y in M(a, a is var z) select x; // error 1 var zd = from x in a from int y in M(a, a is var z) select x; // error 2 var ze = from x in a from y in M(a, a is var z) where true select x; // error 3 var zf = from x in a from int y in M(a, a is var z) where true select x; // error 4 var zg = from x in a let y = M(a, a is var z) select x; // error 5 var zh = from x in a where M(x, x is var z) == 1 select x; // error 6 var zi = from x in a join y in M(a, a is var q2) on x equals y select x; // ok var zj = from x in a join y in a on M(x, x is var z) equals y select x; // error 7 var zk = from x in a join y in a on x equals M(y, y is var z) select x; // error 8 var zl = from x in a orderby M(x, x is var z) select x; // error 9 var zm = from x in a orderby x, M(x, x is var z) select x; // error 10 var zn = from x in a group M(x, x is var z) by x; // error 11 var zo = from x in a group x by M(x, x is var z); // error 12 } public static T M(T x, bool b) => x; }"; CreateCompilationWithMscorlibAndSystemCore(csSource).VerifyDiagnostics( // (10,54): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zc = from x in a from y in M(a, a is var z) select x; // error 1 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(10, 54), // (11,58): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zd = from x in a from int y in M(a, a is var z) select x; // error 2 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(11, 58), // (12,54): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var ze = from x in a from y in M(a, a is var z) where true select x; // error 3 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(12, 54), // (13,58): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zf = from x in a from int y in M(a, a is var z) where true select x; // error 4 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(13, 58), // (14,52): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zg = from x in a let y = M(a, a is var z) select x; // error 5 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(14, 52), // (15,50): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zh = from x in a where M(x, x is var z) == 1 select x; // error 6 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(15, 50), // (17,59): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zj = from x in a join y in a on M(x, x is var z) equals y select x; // error 7 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(17, 59), // (18,68): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zk = from x in a join y in a on x equals M(y, y is var z) select x; // error 8 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(18, 68), // (19,52): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zl = from x in a orderby M(x, x is var z) select x; // error 9 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(19, 52), // (20,55): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zm = from x in a orderby x, M(x, x is var z) select x; // error 10 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(20, 55), // (21,50): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zn = from x in a group M(x, x is var z) by x; // error 11 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(21, 50), // (22,55): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zo = from x in a group x by M(x, x is var z); // error 12 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(22, 55) ); } [WorkItem(15910, "https://github.com/dotnet/roslyn/issues/15910")] [Fact] public void ExpressionVariablesInQueryClause_03() { var csSource = @" using System.Linq; class Program { public static void Main(string[] args) { var a = new[] { (1, 2), (3, 4) }; var za = from x in M(a, (int qa, int wa) = a[0]) select x; // scoping ok var zc = from x in a from y in M(a, (int z, int w) = x) select x; // error 1 var zd = from x in a from int y in M(a, (int z, int w) = x) select x; // error 2 var ze = from x in a from y in M(a, (int z, int w) = x) where true select x; // error 3 var zf = from x in a from int y in M(a, (int z, int w) = x) where true select x; // error 4 var zg = from x in a let y = M(x, (int z, int w) = x) select x; // error 5 var zh = from x in a where M(x, (int z, int w) = x).Item1 == 1 select x; // error 6 var zi = from x in a join y in M(a, (int qi, int wi) = a[0]) on x equals y select x; // scoping ok var zj = from x in a join y in a on M(x, (int z, int w) = x) equals y select x; // error 7 var zk = from x in a join y in a on x equals M(y, (int z, int w) = y) select x; // error 8 var zl = from x in a orderby M(x, (int z, int w) = x) select x; // error 9 var zm = from x in a orderby x, M(x, (int z, int w) = x) select x; // error 10 var zn = from x in a group M(x, (int z, int w) = x) by x; // error 11 var zo = from x in a group x by M(x, (int z, int w) = x); // error 12 } public static T M(T x, (int, int) z) => x; } namespace System { public struct ValueTuple { public T1 Item1; public T2 Item2; public ValueTuple(T1 item1, T2 item2) { this.Item1 = item1; this.Item2 = item2; } } } "; CreateCompilationWithMscorlibAndSystemCore(csSource) .GetDiagnostics() .Where(d => d.Code != (int)ErrorCode.ERR_DeclarationExpressionNotPermitted) .Verify( // (10,50): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zc = from x in a from y in M(a, (int z, int w) = x) select x; // error 1 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(10, 50), // (11,54): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zd = from x in a from int y in M(a, (int z, int w) = x) select x; // error 2 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(11, 54), // (12,50): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var ze = from x in a from y in M(a, (int z, int w) = x) where true select x; // error 3 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(12, 50), // (13,54): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zf = from x in a from int y in M(a, (int z, int w) = x) where true select x; // error 4 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(13, 54), // (14,48): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zg = from x in a let y = M(x, (int z, int w) = x) select x; // error 5 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(14, 48), // (15,46): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zh = from x in a where M(x, (int z, int w) = x).Item1 == 1 select x; // error 6 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(15, 46), // (17,55): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zj = from x in a join y in a on M(x, (int z, int w) = x) equals y select x; // error 7 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(17, 55), // (18,64): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zk = from x in a join y in a on x equals M(y, (int z, int w) = y) select x; // error 8 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(18, 64), // (19,48): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zl = from x in a orderby M(x, (int z, int w) = x) select x; // error 9 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(19, 48), // (20,51): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zm = from x in a orderby x, M(x, (int z, int w) = x) select x; // error 10 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(20, 51), // (21,46): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zn = from x in a group M(x, (int z, int w) = x) by x; // error 11 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(21, 46), // (22,51): error CS8201: Out variable and pattern variable declarations are not allowed within a query clause. // var zo = from x in a group x by M(x, (int z, int w) = x); // error 12 Diagnostic(ErrorCode.ERR_ExpressionVariableInQueryClause, "z").WithLocation(22, 51) ); } [Fact, WorkItem(14689, "https://github.com/dotnet/roslyn/issues/14689")] public void SelectFromNamespaceShouldGiveAnError() { string source = @" using System.Linq; using NSAlias = ParentNamespace.ConsoleApp; namespace ParentNamespace { namespace ConsoleApp { class Program { static void Main() { var x = from c in ConsoleApp select 3; var y = from c in ParentNamespace.ConsoleApp select 3; var z = /**/from c in NSAlias select 3/**/; } } } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: ?, IsInvalid) (Syntax: 'from c in N ... as select 3') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause) (Syntax: 'select 3') ReducedExpression: IInvocationExpression (? ParentNamespace.ConsoleApp.Program.Select()) (OperationKind.InvocationExpression, Type: ?) (Syntax: 'select 3') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument, IsInvalid) (Syntax: 'from c in NSAlias') IInvalidExpression (OperationKind.InvalidExpression, Type: ?, IsInvalid) (Syntax: 'from c in NSAlias') Children(1): IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'from c in NSAlias') ReducedExpression: IOperation: (OperationKind.None, IsInvalid) (Syntax: 'NSAlias') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: null) (OperationKind.Argument) (Syntax: '3') ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null) (Syntax: '3') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '3') IReturnStatement (OperationKind.ReturnStatement) (Syntax: '3') ReturnedValue: ILiteralExpression (Text: 3) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 3) (Syntax: '3') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0119: 'ConsoleApp' is a namespace, which is not valid in the given context // var x = from c in ConsoleApp select 3; Diagnostic(ErrorCode.ERR_BadSKunknown, "ConsoleApp").WithArguments("ConsoleApp", "namespace").WithLocation(13, 35), // CS0119: 'ParentNamespace.ConsoleApp' is a namespace, which is not valid in the given context // var y = from c in ParentNamespace.ConsoleApp select 3; Diagnostic(ErrorCode.ERR_BadSKunknown, "ParentNamespace.ConsoleApp").WithArguments("ParentNamespace.ConsoleApp", "namespace").WithLocation(14, 35), // CS0119: 'NSAlias' is a namespace, which is not valid in the given context // var z = /**/from c in NSAlias select 3/**/; Diagnostic(ErrorCode.ERR_BadSKunknown, "NSAlias").WithArguments("NSAlias", "namespace").WithLocation(15, 45) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } [Fact, WorkItem(12052, "https://github.com/dotnet/roslyn/issues/12052")] public void LambdaParameterConflictsWithRangeVariable() { string source = @" using System; using System.Linq; class Program { static void Main() { var res = /**/from a in new[] { 1 } select (Func)(a => 1)/**/; } } "; string expectedOperationTree = @" IQueryExpression (OperationKind.QueryExpression, Type: System.Collections.Generic.IEnumerable>, IsInvalid) (Syntax: 'from a in n ... t>)(a => 1)') LastClauseOrContinuation: ISelectQueryClause (Clause kind: SelectClause) (OperationKind.QueryClause, IsInvalid) (Syntax: 'select (Fun ... t>)(a => 1)') ReducedExpression: 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>, IsInvalid) (Syntax: 'select (Fun ... t>)(a => 1)') Instance Receiver: null Arguments(2): IArgument (ArgumentKind.Explicit, Matching Parameter: source) (OperationKind.Argument) (Syntax: 'from a in new[] { 1 }') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Collections.Generic.IEnumerable) (Syntax: 'from a in new[] { 1 }') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: IFromQueryClause (Clause kind: FromClause) (OperationKind.QueryClause) (Syntax: 'from a in new[] { 1 }') ReducedExpression: IArrayCreationExpression (Element Type: System.Int32) (OperationKind.ArrayCreationExpression, Type: System.Int32[]) (Syntax: 'new[] { 1 }') Dimension Sizes(1): ILiteralExpression (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: 'new[] { 1 }') Initializer: IArrayInitializer (1 elements) (OperationKind.ArrayInitializer) (Syntax: '{ 1 }') Element Values(1): ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') InConversion: null OutConversion: null IArgument (ArgumentKind.Explicit, Matching Parameter: selector) (OperationKind.Argument, IsInvalid) (Syntax: '(Func)(a => 1)') IConversionExpression (Implicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func>, IsInvalid) (Syntax: '(Func)(a => 1)') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: '(Func)(a => 1)') IBlockStatement (1 statements) (OperationKind.BlockStatement, IsInvalid) (Syntax: '(Func)(a => 1)') IReturnStatement (OperationKind.ReturnStatement, IsInvalid) (Syntax: '(Func)(a => 1)') ReturnedValue: IConversionExpression (Explicit, TryCast: False, Unchecked) (OperationKind.ConversionExpression, Type: System.Func, IsInvalid) (Syntax: '(Func)(a => 1)') Conversion: CommonConversion (Exists: True, IsIdentity: True, IsNumeric: False, IsReference: False, IsUserDefined: False) (MethodSymbol: null) Operand: ILambdaExpression (Signature: lambda expression) (OperationKind.LambdaExpression, Type: null, IsInvalid) (Syntax: 'a => 1') IBlockStatement (1 statements) (OperationKind.BlockStatement) (Syntax: '1') IReturnStatement (OperationKind.ReturnStatement) (Syntax: '1') ReturnedValue: ILiteralExpression (Text: 1) (OperationKind.LiteralExpression, Type: System.Int32, Constant: 1) (Syntax: '1') InConversion: null OutConversion: null "; var expectedDiagnostics = new DiagnosticDescription[] { // CS0136: A local or parameter named 'a' cannot be declared in this scope because that name is used in an enclosing local scope to define a local or parameter // select (Func)(a => 1)/**/; Diagnostic(ErrorCode.ERR_LocalIllegallyOverrides, "a").WithArguments("a").WithLocation(10, 43) }; VerifyOperationTreeAndDiagnosticsForTest(source, expectedOperationTree, expectedDiagnostics); } } }