<Compile Include="System.Linq.Expressions\EmitContext.cs" />\r
<Compile Include="System.Linq.Expressions\Expression.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionPrinter.cs" />\r
+ <Compile Include="System.Linq.Expressions\ExpressionTransformer.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionType.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionVisitor.cs" />\r
<Compile Include="System.Linq.Expressions\Expression_T.cs" />\r
<Compile Include="System.Linq\OrderedEnumerable.cs" />\r
<Compile Include="System.Linq\OrderedSequence.cs" />\r
<Compile Include="System.Linq\Queryable.cs" />\r
+ <Compile Include="System.Linq\QueryableEnumerable.cs" />\r
+ <Compile Include="System.Linq\QueryableTransformer.cs" />\r
<Compile Include="System.Linq\QuickSort.cs" />\r
<Compile Include="System.Linq\SortContext.cs" />\r
<Compile Include="System.Linq\SortDirection.cs" />\r
<Folder Include="System.Runtime.CompilerServices\.svn\tmp\props\" />\r
<Folder Include="System.Runtime.CompilerServices\.svn\tmp\text-base\" />\r
</ItemGroup>\r
-</Project>\r
+</Project>
\ No newline at end of file
<Compile Include="System.Linq.Expressions\ElementInit.cs" />\r
<Compile Include="System.Linq.Expressions\Expression.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionPrinter.cs" />\r
+ <Compile Include="System.Linq.Expressions\ExpressionTransformer.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionType.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionVisitor.cs" />\r
<Compile Include="System.Linq.Expressions\Expression_T.cs" />\r
<Compile Include="System.Linq.Expressions\TypeBinaryExpression.cs" />\r
<Compile Include="System.Linq.Expressions\UnaryExpression.cs" />\r
<Compile Include="System.Linq\Check.cs" />\r
+ <Compile Include="System.Linq\QueryableEnumerable.cs" />\r
+ <Compile Include="System.Linq\QueryableTransformer.cs" />\r
<Compile Include="System.Linq\QuickSort.cs" />\r
<Compile Include="System.Linq\SortSequenceContext.cs" />\r
<Compile Include="System.Linq\SortContext.cs" />\r
\r
Microsoft Visual Studio Solution File, Format Version 10.00\r
-# Visual C# Express 2008\r
+# Visual Studio 2008\r
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Core-2008", "System.Core-2008.csproj", "{D287D5CA-4F81-4215-AFC8-8A1413696884}"\r
EndProject\r
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Core.Tests-2008", "Test\System.Core.Tests-2008.csproj", "{F902A50D-6156-4935-A1AC-E82DF0EB83D3}"\r
EndProject\r
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6DD21DC4-1760-412E-BA3B-9295911E8794}"\r
+ ProjectSection(SolutionItems) = preProject\r
+ LocalTestRun.testrunconfig = LocalTestRun.testrunconfig\r
+ System.Core-2008.vsmdi = System.Core-2008.vsmdi\r
+ EndProjectSection\r
+EndProject\r
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LINQIntro", "..\LINQIntro\LINQIntro.csproj", "{9C0334A8-9E1C-4581-A547-46DD4D957E76}"\r
+EndProject\r
Global\r
GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
Debug|Any CPU = Debug|Any CPU\r
{F902A50D-6156-4935-A1AC-E82DF0EB83D3}.Release|Any CPU.Build.0 = Release|Any CPU\r
{F902A50D-6156-4935-A1AC-E82DF0EB83D3}.Test.NET|Any CPU.ActiveCfg = Test.NET|Any CPU\r
{F902A50D-6156-4935-A1AC-E82DF0EB83D3}.Test.NET|Any CPU.Build.0 = Test.NET|Any CPU\r
+ {9C0334A8-9E1C-4581-A547-46DD4D957E76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+ {9C0334A8-9E1C-4581-A547-46DD4D957E76}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+ {9C0334A8-9E1C-4581-A547-46DD4D957E76}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+ {9C0334A8-9E1C-4581-A547-46DD4D957E76}.Release|Any CPU.Build.0 = Release|Any CPU\r
+ {9C0334A8-9E1C-4581-A547-46DD4D957E76}.Test.NET|Any CPU.ActiveCfg = Release|Any CPU\r
+ {9C0334A8-9E1C-4581-A547-46DD4D957E76}.Test.NET|Any CPU.Build.0 = Release|Any CPU\r
EndGlobalSection\r
GlobalSection(SolutionProperties) = preSolution\r
HideSolutionNode = FALSE\r
System.Runtime.CompilerServices/StrongBox_T.cs
System.Linq/Check.cs
System.Linq/Enumerable.cs
+System.Linq/QueryableEnumerable.cs
+System.Linq/QueryableTransformer.cs
System.Linq/Grouping.cs
System.Linq/IGrouping.cs
System.Linq/IOrderedQueryable.cs
System.Linq.Expressions/ExpressionPrinter.cs
System.Linq.Expressions/ExpressionType.cs
System.Linq.Expressions/ExpressionVisitor.cs
+System.Linq.Expressions/ExpressionTransformer.cs
System.Linq.Expressions/Extensions.cs
System.Linq.Expressions/InvocationExpression.cs
System.Linq.Expressions/LambdaExpression.cs
System.Collections.Generic/HashSetTest.cs
System.Linq/EnumerableTest.cs
System.Linq/EnumerableMoreTest.cs
+System.Linq/EnumerableAsQueryableTest.cs
System.Linq.Expressions/ExpressionTest.cs
System.Linq.Expressions/ExpressionTest_Add.cs
System.Linq.Expressions/ExpressionTest_AddChecked.cs
+2008-05-15 Roei Erez <roeie@mainsoft.com>
+
+ * ExpressionTransformer.cs: Add a base class for transforming Expressions.
+ In use at AsQueryable() implementation.
+
2008-05-14 Jb Evain <jbevain@novell.com>
* EmitContext.cs: only generate a new lambda name if we're in
--- /dev/null
+//\r
+// ExpressionTransformer.cs\r
+//\r
+// Authors:\r
+// Roei Erez (roeie@mainsoft.com)\r
+//\r
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Linq.Expressions;\r
+using System.Text;\r
+using System.Collections.ObjectModel;\r
+\r
+namespace System.Linq\r
+{\r
+ abstract class ExpressionTransformer\r
+ {\r
+\r
+ protected ExpressionTransformer ()\r
+ {\r
+ }\r
+\r
+ public Expression Transform (Expression e)\r
+ {\r
+ return Visit (e);\r
+ }\r
+\r
+ protected virtual Expression Visit (Expression expression)\r
+ {\r
+ if (expression == null)\r
+ return null;\r
+\r
+ switch (expression.NodeType) {\r
+ case ExpressionType.Negate:\r
+ case ExpressionType.NegateChecked:\r
+ case ExpressionType.Not:\r
+ case ExpressionType.Convert:\r
+ case ExpressionType.ConvertChecked:\r
+ case ExpressionType.ArrayLength:\r
+ case ExpressionType.Quote:\r
+ case ExpressionType.TypeAs:\r
+ case ExpressionType.UnaryPlus:\r
+ return VisitUnary ((UnaryExpression) expression);\r
+ case ExpressionType.Add:\r
+ case ExpressionType.AddChecked:\r
+ case ExpressionType.Subtract:\r
+ case ExpressionType.SubtractChecked:\r
+ case ExpressionType.Multiply:\r
+ case ExpressionType.MultiplyChecked:\r
+ case ExpressionType.Divide:\r
+ case ExpressionType.Modulo:\r
+ case ExpressionType.Power:\r
+ case ExpressionType.And:\r
+ case ExpressionType.AndAlso:\r
+ case ExpressionType.Or:\r
+ case ExpressionType.OrElse:\r
+ case ExpressionType.LessThan:\r
+ case ExpressionType.LessThanOrEqual:\r
+ case ExpressionType.GreaterThan:\r
+ case ExpressionType.GreaterThanOrEqual:\r
+ case ExpressionType.Equal:\r
+ case ExpressionType.NotEqual:\r
+ case ExpressionType.Coalesce:\r
+ case ExpressionType.ArrayIndex:\r
+ case ExpressionType.RightShift:\r
+ case ExpressionType.LeftShift:\r
+ case ExpressionType.ExclusiveOr:\r
+ return VisitBinary ((BinaryExpression) expression);\r
+ case ExpressionType.TypeIs:\r
+ return VisitTypeIs ((TypeBinaryExpression) expression);\r
+ case ExpressionType.Conditional:\r
+ return VisitConditional ((ConditionalExpression) expression);\r
+ case ExpressionType.Constant:\r
+ return VisitConstant ((ConstantExpression) expression);\r
+ case ExpressionType.Parameter:\r
+ return VisitParameter ((ParameterExpression) expression);\r
+ case ExpressionType.MemberAccess:\r
+ return VisitMemberAccess ((MemberExpression) expression);\r
+ case ExpressionType.Call:\r
+ return VisitMethodCall ((MethodCallExpression) expression);\r
+ case ExpressionType.Lambda:\r
+ return VisitLambda ((LambdaExpression) expression);\r
+ case ExpressionType.New:\r
+ return VisitNew ((NewExpression) expression);\r
+ case ExpressionType.NewArrayInit:\r
+ case ExpressionType.NewArrayBounds:\r
+ return VisitNewArray ((NewArrayExpression) expression);\r
+ case ExpressionType.Invoke:\r
+ return VisitInvocation ((InvocationExpression) expression);\r
+ case ExpressionType.MemberInit:\r
+ return VisitMemberInit ((MemberInitExpression) expression);\r
+ case ExpressionType.ListInit:\r
+ return VisitListInit ((ListInitExpression) expression);\r
+ default:\r
+ throw new ArgumentException (string.Format ("Unhandled expression type: '{0}'", expression.NodeType));\r
+ }\r
+ }\r
+\r
+ protected virtual MemberBinding VisitBinding (MemberBinding binding)\r
+ {\r
+ switch (binding.BindingType) {\r
+ case MemberBindingType.Assignment:\r
+ return VisitMemberAssignment ((MemberAssignment) binding); \r
+ case MemberBindingType.MemberBinding:\r
+ return VisitMemberMemberBinding ((MemberMemberBinding) binding);\r
+ case MemberBindingType.ListBinding:\r
+ return VisitMemberListBinding ((MemberListBinding) binding);\r
+ default:\r
+ throw new ArgumentException (string.Format ("Unhandled binding type '{0}'", binding.BindingType));\r
+ }\r
+ }\r
+\r
+ protected virtual ElementInit VisitElementInitializer (ElementInit initializer)\r
+ {\r
+ ReadOnlyCollection<Expression> transformed = VisitExpressionList (initializer.Arguments);\r
+ if (transformed != initializer.Arguments)\r
+ return Expression.ElementInit (initializer.AddMethod, transformed);\r
+ return initializer;\r
+ }\r
+\r
+ protected virtual UnaryExpression VisitUnary (UnaryExpression unary)\r
+ {\r
+ Expression transformedOperand = Visit (unary.Operand);\r
+ if (transformedOperand != unary.Operand)\r
+ return Expression.MakeUnary (unary.NodeType, transformedOperand, unary.Type, unary.Method);\r
+ return unary;\r
+ }\r
+\r
+ protected virtual BinaryExpression VisitBinary (BinaryExpression binary)\r
+ {\r
+ Expression left = Visit (binary.Left);\r
+ Expression right = Visit (binary.Right);\r
+ LambdaExpression conversion = VisitLambda (binary.Conversion);\r
+ if (left != binary.Left || right != binary.Right || conversion != binary.Conversion)\r
+ return Expression.MakeBinary (binary.NodeType, left, right, binary.IsLiftedToNull, binary.Method, conversion);\r
+ return binary;\r
+ }\r
+\r
+ protected virtual TypeBinaryExpression VisitTypeIs (TypeBinaryExpression type)\r
+ {\r
+ Expression inner = Visit (type.Expression);\r
+ if (inner != type.Expression)\r
+ return Expression.TypeIs (inner, type.TypeOperand);\r
+ return type;\r
+ }\r
+\r
+ protected virtual ConstantExpression VisitConstant (ConstantExpression constant)\r
+ {\r
+ return constant;\r
+ }\r
+\r
+ protected virtual ConditionalExpression VisitConditional (ConditionalExpression conditional)\r
+ {\r
+ Expression test = Visit (conditional.Test);\r
+ Expression ifTrue = Visit (conditional.IfTrue);\r
+ Expression ifFalse = Visit (conditional.IfFalse);\r
+ if (test != conditional.Test || ifTrue != conditional.IfTrue || ifFalse != conditional.IfFalse)\r
+ return Expression.Condition (test, ifTrue, ifFalse);\r
+ return conditional;\r
+ }\r
+\r
+ protected virtual ParameterExpression VisitParameter (ParameterExpression parameter)\r
+ {\r
+ return parameter;\r
+ }\r
+\r
+ protected virtual MemberExpression VisitMemberAccess (MemberExpression member)\r
+ {\r
+ Expression memberExp = Visit (member.Expression);\r
+ if (memberExp != member.Expression)\r
+ return Expression.MakeMemberAccess (memberExp, member.Member);\r
+ return member;\r
+ }\r
+\r
+ protected virtual MethodCallExpression VisitMethodCall (MethodCallExpression methodCall)\r
+ {\r
+ Expression instance = Visit (methodCall.Object);\r
+ ReadOnlyCollection<Expression> args = VisitExpressionList (methodCall.Arguments);\r
+ if (instance != methodCall.Object || args != methodCall.Arguments)\r
+ return Expression.Call (instance, methodCall.Method, args);\r
+ return methodCall;\r
+ } \r
+\r
+ protected virtual ReadOnlyCollection<Expression> VisitExpressionList (ReadOnlyCollection<Expression> list)\r
+ {\r
+ return VisitList<Expression> (list, Visit); \r
+ }\r
+\r
+ private ReadOnlyCollection<T> VisitList<T> (ReadOnlyCollection<T> list, Func<T,T> selector) where T :class\r
+ {\r
+ int index = 0;\r
+ T [] arr = null;\r
+ foreach (T e in list) {\r
+ T visited = selector (e);\r
+ if (visited != e || arr != null) {\r
+ if (arr == null)\r
+ arr = new T [list.Count];\r
+ arr [index] = visited;\r
+ }\r
+ index++;\r
+ }\r
+ if (arr != null)\r
+ return arr.ToReadOnlyCollection ();\r
+ return list;\r
+ }\r
+\r
+ protected virtual MemberAssignment VisitMemberAssignment (MemberAssignment assignment)\r
+ {\r
+ Expression inner = Visit (assignment.Expression);\r
+ if (inner != assignment.Expression)\r
+ return Expression.Bind (assignment.Member, inner);\r
+ return assignment;\r
+ }\r
+\r
+ protected virtual MemberMemberBinding VisitMemberMemberBinding (MemberMemberBinding binding)\r
+ {\r
+ ReadOnlyCollection<MemberBinding> bindingExp = VisitBindingList (binding.Bindings);\r
+ if (bindingExp != binding.Bindings)\r
+ return Expression.MemberBind (binding.Member, bindingExp);\r
+ return binding;\r
+ }\r
+\r
+ protected virtual MemberListBinding VisitMemberListBinding (MemberListBinding binding)\r
+ {\r
+ ReadOnlyCollection<ElementInit> initializers = \r
+ VisitElementInitializerList (binding.Initializers);\r
+ if (initializers != binding.Initializers)\r
+ return Expression.ListBind (binding.Member, initializers);\r
+ return binding;\r
+ }\r
+\r
+ protected virtual ReadOnlyCollection<MemberBinding> VisitBindingList (ReadOnlyCollection<MemberBinding> list)\r
+ {\r
+ return VisitList<MemberBinding> (list, VisitBinding);\r
+ }\r
+\r
+ protected virtual ReadOnlyCollection<ElementInit> VisitElementInitializerList (ReadOnlyCollection<ElementInit> list)\r
+ {\r
+ return VisitList<ElementInit> (list, VisitElementInitializer);\r
+ }\r
+\r
+ protected virtual LambdaExpression VisitLambda (LambdaExpression lambda)\r
+ {\r
+ Expression body = Visit (lambda.Body);\r
+ ReadOnlyCollection<ParameterExpression> parameters = \r
+ VisitList<ParameterExpression> (lambda.Parameters, VisitParameter);\r
+ if (body != lambda.Body || parameters != lambda.Parameters)\r
+ return Expression.Lambda (body, parameters.ToArray());\r
+ return lambda;\r
+ }\r
+\r
+ protected virtual NewExpression VisitNew (NewExpression nex)\r
+ {\r
+ ReadOnlyCollection<Expression> args = VisitList (nex.Arguments, Visit);\r
+ if (args != nex.Arguments)\r
+ return Expression.New (nex.Constructor, args);\r
+ return nex;\r
+ }\r
+\r
+ protected virtual MemberInitExpression VisitMemberInit (MemberInitExpression init)\r
+ {\r
+ NewExpression newExp = VisitNew (init.NewExpression);\r
+ ReadOnlyCollection<MemberBinding> bindings = VisitBindingList (init.Bindings);\r
+ if (newExp != init.NewExpression || bindings != init.Bindings)\r
+ return Expression.MemberInit (newExp, bindings);\r
+ return init;\r
+ }\r
+\r
+ protected virtual ListInitExpression VisitListInit (ListInitExpression init)\r
+ {\r
+ NewExpression newExp = VisitNew (init.NewExpression);\r
+ ReadOnlyCollection<ElementInit> initializers = VisitElementInitializerList (init.Initializers);\r
+ if (newExp != init.NewExpression || initializers != init.Initializers)\r
+ return Expression.ListInit (newExp, initializers.ToArray());\r
+ return init;\r
+ }\r
+\r
+ protected virtual NewArrayExpression VisitNewArray (NewArrayExpression newArray)\r
+ {\r
+ ReadOnlyCollection<Expression> expressions = VisitExpressionList (newArray.Expressions);\r
+ if (expressions != newArray.Expressions) {\r
+ if (newArray.NodeType == ExpressionType.NewArrayBounds)\r
+ return Expression.NewArrayBounds (newArray.Type, expressions);\r
+ else\r
+ return Expression.NewArrayInit (newArray.Type, expressions);\r
+ }\r
+ return newArray;\r
+ }\r
+\r
+ protected virtual InvocationExpression VisitInvocation (InvocationExpression invocation)\r
+ {\r
+ ReadOnlyCollection<Expression> args = VisitExpressionList (invocation.Arguments);\r
+ Expression invocationExp = Visit (invocation.Expression);\r
+ if (args != invocation.Arguments || invocationExp != invocation.Expression)\r
+ return Expression.Invoke (invocationExp, args);\r
+ return invocation;\r
+ }\r
+ }\r
+}\r
+2008-05-15 Roei Erez <roeie@mainsoft.com>
+
+ * QueryableTransformer.cs, QueryableEnumerable.cs: two classes added for implementation
+ of Queryable.AsQueryable() implementation.
+ * Queryable.cs: Implement AsQueryable() method.
+
2008-05-08 Jonathan Pryor <jpryor@novell.com>
* Enumerable.cs: LongCount() can be optimized for arrays, and Reverse() can
if (queryable != null)
return queryable;
- throw new NotImplementedException ();
+ return new QueryableEnumerable<TElement> (new ConstantExpression (source, typeof (IQueryable<TElement>)));
}
[MonoTODO]
--- /dev/null
+//\r
+// QueryableEnumerable<TElement>.cs\r
+//\r
+// Authors:\r
+// Roei Erez (roeie@mainsoft.com)\r
+//\r
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Linq.Expressions;\r
+\r
+namespace System.Linq\r
+{\r
+ internal class QueryableEnumerable<TElement> : IQueryable<TElement>, IQueryProvider, IOrderedQueryable<TElement>\r
+ { \r
+ Expression expression;\r
+\r
+ public QueryableEnumerable (Expression expression) {\r
+ this.expression = expression;\r
+ }\r
+\r
+ public Type ElementType {\r
+ get { return expression.Type; }\r
+ }\r
+\r
+ public Expression Expression {\r
+ get { return expression; }\r
+ }\r
+\r
+ public IQueryProvider Provider {\r
+ get { return this; }\r
+ }\r
+\r
+ public System.Collections.IEnumerator GetEnumerator () \r
+ { \r
+ return ((IEnumerable<TElement>)this).GetEnumerator ();\r
+ }\r
+\r
+ IEnumerator<TElement> IEnumerable<TElement>.GetEnumerator () \r
+ {\r
+ return Execute<IEnumerable<TElement>> (Expression).GetEnumerator ();\r
+ }\r
+\r
+ public IQueryable CreateQuery (System.Linq.Expressions.Expression expression) \r
+ {\r
+ return (IQueryable) Activator.CreateInstance (\r
+ typeof (QueryableEnumerable<>).MakeGenericType (expression.Type.GetGenericArguments()[0]), expression); \r
+ }\r
+\r
+ public object Execute (System.Linq.Expressions.Expression expression) \r
+ {\r
+ QueryableTransformer visitor = new QueryableTransformer ();\r
+ Expression body = visitor.Transform (expression);\r
+ LambdaExpression lambda = Expression.Lambda (body); \r
+ return lambda.Compile ().DynamicInvoke();\r
+ }\r
+\r
+ public IQueryable<TElem> CreateQuery<TElem> (System.Linq.Expressions.Expression expression) \r
+ {\r
+ return new QueryableEnumerable<TElem> (expression);\r
+ }\r
+\r
+ public TResult Execute<TResult> (System.Linq.Expressions.Expression expression) \r
+ {\r
+ QueryableTransformer visitor = new QueryableTransformer ();\r
+ Expression body = visitor.Transform (expression);\r
+ Expression<Func<TResult>> lambda = Expression.Lambda<Func<TResult>> (body);\r
+ return lambda.Compile () ();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+//\r
+// QueryableTransformer.cs\r
+//\r
+// Authors:\r
+// Roei Erez (roeie@mainsoft.com)\r
+//\r
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using System.Linq.Expressions;\r
+using System.Reflection;\r
+using System.Runtime.CompilerServices;\r
+using System.Collections.ObjectModel;\r
+\r
+namespace System.Linq\r
+{\r
+ internal class QueryableTransformer : ExpressionTransformer\r
+ { \r
+\r
+ internal QueryableTransformer () {}\r
+ \r
+ protected override MethodCallExpression VisitMethodCall (MethodCallExpression methodCall) \r
+ { \r
+ if ( IsQueryableExtension ( methodCall.Method ))\r
+ {\r
+ return ReplaceIQueryableMethod (methodCall);\r
+ }\r
+ return base.VisitMethodCall (methodCall);\r
+ }\r
+\r
+ protected override LambdaExpression VisitLambda (LambdaExpression lambda) \r
+ {\r
+ return lambda;\r
+ } \r
+\r
+ bool IsQueryableExtension (MethodInfo method) \r
+ {\r
+ return method.GetCustomAttributes(typeof(ExtensionAttribute), false).Count() > 0 && \r
+ typeof(IQueryable).IsAssignableFrom( method.GetParameters () [0].ParameterType );\r
+ }\r
+\r
+ MethodCallExpression ReplaceIQueryableMethod (MethodCallExpression oldCall)\r
+ { \r
+ Expression target = null;\r
+ if (oldCall.Object != null){\r
+ target = Visit (oldCall.Object);\r
+ } \r
+ MethodInfo newMethod = ReplaceIQueryableMethodInfo(oldCall.Method);\r
+\r
+ Expression [] args = new Expression [oldCall.Arguments.Count];\r
+ int counter = 0;\r
+ foreach (Expression e in oldCall.Arguments) { \r
+ Type methodParam = newMethod.GetParameters() [counter].ParameterType; \r
+ args [counter++] = ReplaceQuotedLambdaIfNeeded(Visit (e), methodParam);\r
+ }\r
+ ReadOnlyCollection<Expression> col = args.ToReadOnlyCollection();\r
+ MethodCallExpression newMethodCall = new MethodCallExpression (target, newMethod, col);\r
+ return newMethodCall;\r
+ }\r
+\r
+ static Expression ReplaceQuotedLambdaIfNeeded (Expression e, Type delegateType)\r
+ {\r
+ UnaryExpression unary = e as UnaryExpression;\r
+ if (unary != null) {\r
+ LambdaExpression lambda = unary.Operand as LambdaExpression;\r
+ if (lambda != null && lambda.Type == delegateType)\r
+ return lambda;\r
+ }\r
+ return e;\r
+ }\r
+\r
+ static MethodInfo ReplaceIQueryableMethodInfo (MethodInfo qm) \r
+ {\r
+ Type typeToSearch = qm.DeclaringType == typeof (Queryable) ? typeof (Enumerable) : qm.DeclaringType;\r
+ MethodInfo result = GetMatchingMethod (qm, typeToSearch); \r
+ if (result == null)\r
+ throw new InvalidOperationException (\r
+ string.Format("There is no method {0} on type {1} that matches the specified arguments", \r
+ qm.Name, \r
+ qm.DeclaringType.FullName));\r
+ return result;\r
+ }\r
+\r
+ static MethodInfo GetMatchingMethod (MethodInfo qm, Type fromType)\r
+ {\r
+ return (from em in fromType.GetMethods ()\r
+ where Match (em, qm)\r
+ select em.MakeGenericMethod (qm.GetGenericArguments ()))\r
+ .FirstOrDefault ();\r
+ }\r
+\r
+ static bool Match (MethodInfo em, MethodInfo qm) {\r
+\r
+ if (em.GetCustomAttributes (typeof (ExtensionAttribute), false).Count() == 0)\r
+ return false;\r
+\r
+ if (em.Name != qm.Name)\r
+ return false; \r
+\r
+ if (em.GetGenericArguments ().Length != qm.GetGenericArguments ().Length)\r
+ return false; \r
+\r
+ Type [] parameters = (from p in qm.GetParameters () select p.ParameterType).ToArray ();\r
+ Type returnType = qm.ReturnType;\r
+ \r
+ if (parameters.Length != em.GetParameters ().Length)\r
+ return false;\r
+\r
+ MethodInfo instanceMethod = em;\r
+ if (qm.IsGenericMethod) {\r
+ if (!qm.IsGenericMethod)\r
+ return false;\r
+ if (em.GetParameters ().Length != qm.GetParameters ().Length)\r
+ return false;\r
+ Type [] genArgs = qm.GetGenericArguments ();\r
+ instanceMethod = em.MakeGenericMethod (genArgs);\r
+ }\r
+\r
+ Type [] enumerableParams = (from p in instanceMethod.GetParameters () select p.ParameterType).ToArray ();\r
+\r
+ if (enumerableParams [0] != ConvertParameter (parameters [0]))\r
+ return false;\r
+ for (int i = 1; i < enumerableParams.Length; ++i)\r
+ if (!ArgumentMatch(enumerableParams [i], parameters [i]))\r
+ return false;\r
+ if (!ArgumentMatch(instanceMethod.ReturnType, returnType))\r
+ return false;\r
+ return true;\r
+ }\r
+\r
+ static bool ArgumentMatch (Type enumerableParam, Type queryableParam)\r
+ {\r
+ return enumerableParam == queryableParam || enumerableParam == ConvertParameter (queryableParam);\r
+ }\r
+\r
+ static Type ConvertParameter (Type type) \r
+ {\r
+ if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (IQueryable<>))\r
+ type = typeof (IEnumerable<>).MakeGenericType (type.GetGenericArguments ());\r
+ else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (IOrderedQueryable<>))\r
+ type = typeof (IOrderedEnumerable<>).MakeGenericType (type.GetGenericArguments ());\r
+ else if (type.IsGenericType && type.GetGenericTypeDefinition () == typeof (Expression<>))\r
+ type = type.GetGenericArguments () [0];\r
+ else if (type == typeof (IQueryable))\r
+ type = typeof (System.Collections.IEnumerable);\r
+ return type;\r
+ } \r
+ }\r
+}\r
-->\r
<ProjectExtensions>\r
<VisualStudio>\r
- <UserProperties REFS-RefInfo-rt="repository:jre:sun:1.6.0" REFS-JarPath-rt="" REFS-JarPath-nunit-framework="..\..\..\nunit20\framework\bin\Debug_Java20\nunit.framework.jar" REFS-RefInfo-nunit-framework="j2il:" REFS-JarPath-system="" REFS-RefInfo-system="repository:vmw:framework:2.0" REFS-JarPath-system-core-2008-javaee="..\bin\Debug_Java\System.Core-2008.JavaEE.jar" REFS-RefInfo-system-core-2008-javaee="j2il:" REFS-JarPath-system-core="" REFS-RefInfo-system-core="repository:vmw:framework:2.0" />\r
+ <UserProperties REFS-RefInfo-system-core="repository:vmw:framework:2.0" REFS-JarPath-system-core="" REFS-RefInfo-system-core-2008-javaee="j2il:" REFS-JarPath-system-core-2008-javaee="..\bin\Debug_Java\System.Core-2008.JavaEE.jar" REFS-RefInfo-system="repository:vmw:framework:2.0" REFS-JarPath-system="" REFS-RefInfo-nunit-framework="j2il:" REFS-JarPath-nunit-framework="..\..\..\nunit20\framework\bin\Debug_Java20\nunit.framework.jar" REFS-JarPath-rt="" REFS-RefInfo-rt="repository:jre:sun:1.6.0" />\r
</VisualStudio>\r
</ProjectExtensions>\r
<ItemGroup>\r
</BootstrapperPackage>\r
</ItemGroup>\r
<ItemGroup>\r
+ <None Include="System.Collections.Generic\ChangeLog" />\r
<None Include="System.Linq.Expressions\ChangeLog" />\r
<None Include="System.Linq\ChangeLog" />\r
+ <None Include="System\ChangeLog" />\r
</ItemGroup>\r
<ItemGroup>\r
+ <Compile Include="System.Collections.Generic\HashSetTest.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest_Add.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest_AddChecked.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest_TypeIs.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest_UnaryPlus.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest_Utils.cs" />\r
+ <Compile Include="System.Linq\EnumerableAsQueryableTest.cs" />\r
<Compile Include="System.Linq\EnumerableMoreTest.cs" />\r
<Compile Include="System.Linq\EnumerableTest.cs" />\r
<Compile Include="System.Linq\QueryableProviderTest.cs" />\r
<Compile Include="System.Linq\QueryableTest.cs" />\r
+ <Compile Include="System\TimeZoneInfo.AdjustmentRuleTest.cs" />\r
+ <Compile Include="System\TimeZoneInfo.TransitionTimeTest.cs" />\r
+ <Compile Include="System\TimeZoneInfoTest.cs" />\r
</ItemGroup>\r
<ItemGroup>\r
<Folder Include="Properties\" />\r
</ItemGroup>\r
-</Project>
\ No newline at end of file
+</Project>\r
<Compile Include="System.Linq.Expressions\ExpressionTest_TypeIs.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest_UnaryPlus.cs" />\r
<Compile Include="System.Linq.Expressions\ExpressionTest_Utils.cs" />\r
+ <Compile Include="System.Linq\EnumerableAsQueryableTest.cs" />\r
<Compile Include="System.Linq\EnumerableMoreTest.cs" />\r
<Compile Include="System.Linq\EnumerableTest.cs" />\r
<Compile Include="System.Linq\QueryableProviderTest.cs" />\r
<Target Name="AfterBuild">\r
</Target>\r
-->\r
-</Project>
\ No newline at end of file
+</Project>\r
+2008-05-15 Roei Erez <roeie@mainsoft.com>
+
+ * EnumerableAsQueryableTest.cs: test cases for Queryable.AsQueryable() implementation.
+
2008-05-08 Jonathan Pryor <jpryor@novell.com>
* EnumerableTest.cs: test Reverse() for non-IList types.
--- /dev/null
+//\r
+// EnumerableAsQueryableTest.cs\r
+//\r
+// Authors:\r
+// Roei Erez (roeie@mainsoft.com)\r
+//\r
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)\r
+//\r
+// Permission is hereby granted, free of charge, to any person obtaining\r
+// a copy of this software and associated documentation files (the\r
+// "Software"), to deal in the Software without restriction, including\r
+// without limitation the rights to use, copy, modify, merge, publish,\r
+// distribute, sublicense, and/or sell copies of the Software, and to\r
+// permit persons to whom the Software is furnished to do so, subject to\r
+// the following conditions:\r
+//\r
+// The above copyright notice and this permission notice shall be\r
+// included in all copies or substantial portions of the Software.\r
+//\r
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
+//\r
+\r
+using System;\r
+using System.Collections.Generic;\r
+using System.Linq;\r
+using System.Text;\r
+using NUnit.Framework;\r
+using System.Linq.Expressions;\r
+using System.Runtime.CompilerServices;\r
+using System.Reflection;\r
+\r
+namespace MonoTests.System.Linq {\r
+\r
+ [TestFixture]\r
+ public class EnumerableAsQueryableTest {\r
+\r
+ int [] _array;\r
+ IQueryable<int> _src;\r
+\r
+ [SetUp]\r
+ public void MyTestCleanup ()\r
+ {\r
+ _array = new int [] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };\r
+ _src = _array.AsQueryable<int> ();\r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Aggregate () \r
+ {\r
+ Assert.AreEqual (_src.Aggregate<int> ((n, m) => n + m), _array.Aggregate<int> ((n, m) => n + m));\r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void All ()\r
+ {\r
+ Assert.AreEqual (_src.All<int> ((n) => n < 11), _array.All<int> ((n) => n < 11));\r
+ Assert.AreEqual (_src.All<int> ((n) => n < 10), _array.All<int> ((n) => n < 10));\r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Any ()\r
+ {\r
+ Assert.AreEqual (_src.Any<int> (i => i > 5), _array.Any<int> (i => i > 5));\r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Average ()\r
+ {\r
+ Assert.AreEqual (_src.Average<int> ((n) => 11), _array.Average<int> ((n) => 11));\r
+ } \r
+#endif\r
+\r
+ [Test]\r
+ public void Concat ()\r
+ {\r
+ Assert.AreEqual (_src.Concat<int> (_src).Count (), _array.Concat<int> (_src).Count ());\r
+ }\r
+\r
+ [Test]\r
+ public void Contains ()\r
+ {\r
+\r
+ for (int i = 1; i < 20; ++i)\r
+ Assert.AreEqual (_src.Contains<int> (i), _array.Contains<int> (i));\r
+ }\r
+\r
+ [Test]\r
+ public void Count ()\r
+ {\r
+ Assert.AreEqual (_src.Count<int> (), _array.Count<int> ());\r
+ }\r
+\r
+\r
+ [Test]\r
+ public void Distinct ()\r
+ {\r
+ Assert.AreEqual (_src.Distinct<int> ().Count (), _array.Distinct<int> ().Count ());\r
+ Assert.AreEqual (_src.Distinct<int> (new CustomEqualityComparer ()).Count (), _array.Distinct<int> (new CustomEqualityComparer ()).Count ());\r
+ }\r
+\r
+ [Test]\r
+ public void ElementAt ()\r
+ {\r
+ for (int i = 0; i < 10; ++i)\r
+ Assert.AreEqual (_src.ElementAt<int> (i), _array.ElementAt<int> (i)); \r
+ }\r
+\r
+ [Test]\r
+ public void ElementAtOrDefault ()\r
+ {\r
+ for (int i = 0; i < 10; ++i)\r
+ Assert.AreEqual (_src.ElementAtOrDefault<int> (i), _array.ElementAtOrDefault<int> (i));\r
+ Assert.AreEqual (_src.ElementAtOrDefault<int> (100), _array.ElementAtOrDefault<int> (100));\r
+ }\r
+\r
+ [Test]\r
+ public void Except ()\r
+ {\r
+ int [] except = { 1, 2, 3 };\r
+ Assert.AreEqual (_src.Except<int> (except.AsQueryable ()).Count (), _array.Except<int> (except).Count ());\r
+ }\r
+\r
+ [Test]\r
+ public void First ()\r
+ {\r
+ Assert.AreEqual (_src.First<int> (), _array.First<int> ());\r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void FirstOrDefault ()\r
+ {\r
+ Assert.AreEqual (_src.FirstOrDefault<int> ((n) => n > 5), _array.FirstOrDefault<int> ((n) => n > 5));\r
+ Assert.AreEqual (_src.FirstOrDefault<int> ((n) => n > 10), _array.FirstOrDefault<int> ((n) => n > 10));\r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void GroupBy ()\r
+ {\r
+ IQueryable<IGrouping<bool, int>> grouping = _src.GroupBy<int, bool> ((n) => n > 5);\r
+ Assert.AreEqual (grouping.Count(), 2);\r
+ foreach (IGrouping<bool, int> group in grouping) \r
+ {\r
+ Assert.AreEqual(group.Count(), 5); \r
+ }\r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Intersect ()\r
+ {\r
+ int [] subset = { 1, 2, 3 };\r
+ int[] intersection = _src.Intersect<int> (subset.AsQueryable()).ToArray();\r
+ Assert.AreEqual (subset, intersection);\r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Last ()\r
+ {\r
+ Assert.AreEqual (_src.Last<int> ((n) => n > 1), _array.Last<int> ((n) => n > 1)); \r
+ }\r
+#endif\r
+\r
+ [Test]\r
+ public void LastOrDefault ()\r
+ {\r
+ Assert.AreEqual (_src.LastOrDefault<int> (), _array.LastOrDefault<int> ()); \r
+ }\r
+\r
+ [Test]\r
+ public void LongCount ()\r
+ {\r
+ Assert.AreEqual (_src.LongCount<int> (), _array.LongCount<int> ()); \r
+ }\r
+\r
+ [Test]\r
+ public void Max ()\r
+ {\r
+ Assert.AreEqual (_src.Max<int> (), _array.Max<int> ());\r
+ }\r
+\r
+ [Test]\r
+ public void Min ()\r
+ {\r
+ Assert.AreEqual (_src.Min<int> (), _array.Min<int> ()); \r
+ }\r
+\r
+ [Test]\r
+ public void OfType ()\r
+ {\r
+ Assert.AreEqual (_src.OfType<int> ().Count (), _array.OfType<int> ().Count ()); \r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void OrderBy () \r
+ {\r
+ int [] arr1 = _array.OrderBy<int, int> ((n) => n * -1).ToArray ();\r
+ int [] arr2 = _src.OrderBy<int, int> ((n) => n * -1).ToArray ();\r
+ Assert.AreEqual (arr1, arr2);\r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void OrderByDescending ()\r
+ {\r
+ int [] arr1 = _array.OrderBy<int, int> ((n) => n).ToArray ();\r
+ int [] arr2 = _src.OrderBy<int, int> ((n) => n).ToArray ();\r
+ Assert.AreEqual (arr1, arr2);\r
+ }\r
+#endif\r
+\r
+ [Test]\r
+ public void Reverse ()\r
+ {\r
+ int [] arr1 = _array.Reverse<int> ().Reverse ().ToArray ();\r
+ int [] arr2 = _src.Reverse<int> ().Reverse ().ToArray ();\r
+ Assert.AreEqual (arr1, arr2);\r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Select ()\r
+ {\r
+ int [] arr1 = _array.Select<int, int> ((n) => n - 1).ToArray ();\r
+ int [] arr2 = _src.Select<int, int> ((n) => n - 1).ToArray ();\r
+ Assert.AreEqual (arr1, arr2); \r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void SelectMany ()\r
+ {\r
+ int [] arr1 = _array.SelectMany<int, int> ((n) => new int [] { n, n, n }).ToArray ();\r
+ int [] arr2 = _src.SelectMany<int, int> ((n) => new int [] { n, n, n }).ToArray ();\r
+ Assert.AreEqual (arr1, arr2); \r
+ }\r
+#endif\r
+\r
+ [Test]\r
+ public void SequenceEqual ()\r
+ {\r
+ Assert.IsTrue (_src.SequenceEqual<int> (_src)); \r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Single ()\r
+ {\r
+ Assert.AreEqual (_src.Single (n => n == 10), 10); \r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void SingleOrDefault ()\r
+ {\r
+ Assert.AreEqual (_src.SingleOrDefault (n => n == 10), 10);\r
+ Assert.AreEqual (_src.SingleOrDefault (n => n == 11), 0);\r
+ }\r
+#endif\r
+\r
+ [Test]\r
+ public void Skip ()\r
+ {\r
+ int [] arr1 = _array.Skip<int> (5).ToArray ();\r
+ int [] arr2 = _src.Skip<int> (5).ToArray ();\r
+ Assert.AreEqual (arr1, arr2); \r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void SkipWhile ()\r
+ {\r
+ int[] arr1 = _src.SkipWhile<int> ((n) => n < 6).ToArray();\r
+ int[] arr2 = _src.Skip<int> (5).ToArray();\r
+ Assert.AreEqual (arr1, arr2); \r
+ }\r
+#endif\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Sum ()\r
+ {\r
+ Assert.AreEqual (_src.Sum<int> ((n) => n), _array.Sum<int> ((n) => n));\r
+ Assert.AreEqual (_src.Sum<int> ((n) => n + 1), _array.Sum<int> ((n) => n + 1)); \r
+ }\r
+#endif\r
+\r
+ [Test]\r
+ public void Take ()\r
+ {\r
+ int [] arr1 = _array.Take<int> (3).ToArray ();\r
+ int [] arr2 = _src.Take<int> (3).ToArray ();\r
+ Assert.AreEqual (arr1, arr2);\r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void TakeWhile () \r
+ {\r
+ int [] arr1 = _array.TakeWhile<int> (n => n < 6).ToArray ();\r
+ int [] arr2 = _src.TakeWhile<int> (n => n < 6).ToArray ();\r
+ Assert.AreEqual (arr1, arr2);\r
+ }\r
+#endif\r
+\r
+ [Test]\r
+ public void Union ()\r
+ {\r
+ int [] arr1 = _src.ToArray ();\r
+ int[] arr2 = _src.Union (_src).ToArray ();\r
+ Assert.AreEqual (arr1, arr2);\r
+\r
+ int [] arr = { 11,12,13};\r
+ Assert.AreEqual (_src.Union (arr).ToArray (), _array.Union (arr).ToArray ());\r
+ }\r
+\r
+#if TARGET_JVM //TODO: gmcs fails, bug #390666\r
+ [Test]\r
+ public void Where ()\r
+ {\r
+ int[] oddArray1 = _array.Where<int> ((n) => (n % 2) == 1).ToArray();\r
+ int [] oddArray2 = _src.Where<int> ((n) => (n % 2) == 1).ToArray ();\r
+ Assert.AreEqual (oddArray1, oddArray2);\r
+ }\r
+#endif\r
+\r
+ [Test]\r
+ public void UserExtensionMethod ()\r
+ {\r
+ BindingFlags extensionFlags = BindingFlags.Static | BindingFlags.Public; \r
+ MethodInfo method = (from m in typeof (Ext).GetMethods (extensionFlags)\r
+ where (m.Name == "UserQueryableExt1" && m.GetParameters () [0].ParameterType.GetGenericTypeDefinition () == typeof (IQueryable<>))\r
+ select m).FirstOrDefault ().MakeGenericMethod (typeof (int));\r
+ Expression<Func<int, int>> exp = i => i;\r
+ Expression e = Expression.Equal (\r
+ Expression.Constant ("UserEnumerableExt1"),\r
+ Expression.Call (method, _src.Expression, Expression.Quote (exp)));\r
+ Assert.AreEqual (_src.Provider.Execute<bool> (e), true, "UserQueryableExt1");\r
+\r
+ method = (from m in typeof (Ext).GetMethods (extensionFlags)\r
+ where (m.Name == "UserQueryableExt2" && m.GetParameters () [0].ParameterType.GetGenericTypeDefinition () == typeof (IQueryable<>))\r
+ select m).FirstOrDefault ().MakeGenericMethod (typeof (int));\r
+ e = Expression.Equal (\r
+ Expression.Constant ("UserEnumerableExt2"),\r
+ Expression.Call (method, _src.Expression, Expression.Quote (exp)));\r
+ Assert.AreEqual (_src.Provider.Execute<bool> (e), true, "UserQueryableExt2");\r
+ }\r
+\r
+ [Test]\r
+ [ExpectedException (typeof (InvalidOperationException))]\r
+ public void UserExtensionMethodNegative ()\r
+ {\r
+ BindingFlags extensionFlags = BindingFlags.Static | BindingFlags.Public;\r
+ MethodInfo method = (from m in typeof (Ext).GetMethods (extensionFlags)\r
+ where (m.Name == "UserQueryableExt3" && m.GetParameters () [0].ParameterType.GetGenericTypeDefinition () == typeof (IQueryable<>))\r
+ select m).FirstOrDefault ().MakeGenericMethod (typeof (int));\r
+ Expression<Func<int, int>> exp = i => i;\r
+ Expression e = Expression.Call (method, _src.Expression, Expression.Quote (exp), Expression.Constant (10));\r
+ _src.Provider.Execute (e);\r
+ }\r
+\r
+ [Test] \r
+ public void NonGenericMethod () {\r
+ BindingFlags extensionFlags = BindingFlags.Static | BindingFlags.Public;\r
+ MethodInfo method = (from m in typeof (Ext).GetMethods (extensionFlags)\r
+ where (m.Name == "NonGenericMethod" && m.GetParameters () [0].ParameterType.GetGenericTypeDefinition () == typeof (IQueryable<>))\r
+ select m).FirstOrDefault ();\r
+ Expression<Func<int, int>> exp = i => i;\r
+ Expression e = Expression.Call (method, _src.Expression);\r
+ Assert.AreEqual (_src.Provider.Execute (e), "EnumerableNonGenericMethod", "NonGenericMethod");\r
+ }\r
+\r
+ [Test]\r
+ [ExpectedException(typeof(InvalidOperationException))]\r
+ public void InstantiatedGenericMethod () {\r
+ BindingFlags extensionFlags = BindingFlags.Static | BindingFlags.Public;\r
+ MethodInfo method = (from m in typeof (Ext).GetMethods (extensionFlags)\r
+ where (m.Name == "InstantiatedGenericMethod" && m.GetParameters () [0].ParameterType.GetGenericTypeDefinition () == typeof (IQueryable<>))\r
+ select m).FirstOrDefault ().MakeGenericMethod (typeof (int));\r
+ Expression<Func<int, int>> exp = i => i;\r
+ Expression e = Expression.Call (method, _src.Expression, Expression.Constant(0));\r
+ _src.Provider.Execute (e);\r
+ }\r
+ }\r
+\r
+ class CustomEqualityComparer : IEqualityComparer<int> { \r
+\r
+ public bool Equals (int x, int y)\r
+ {\r
+ return true; \r
+ }\r
+\r
+ public int GetHashCode (int obj)\r
+ {\r
+ return 0;\r
+ } \r
+ }\r
+\r
+ public static class Ext {\r
+ \r
+ public static string UserQueryableExt1<T> (this IQueryable<T> e, Expression<Func<int, int>> ex)\r
+ {\r
+ return "UserQueryableExt1";\r
+ }\r
+\r
+ public static string UserQueryableExt2<T> (this IQueryable<T> e, Expression<Func<int, int>> ex)\r
+ {\r
+ return "UserQueryableExt2";\r
+ }\r
+\r
+ public static string UserQueryableExt3<T> (this IQueryable<T> e, Expression<Func<int, int>> ex, int dummy)\r
+ {\r
+ return "UserQueryableExt3";\r
+ }\r
+\r
+ public static string UserQueryableExt1<T> (this IEnumerable<T> e, Expression<Func<int, int>> ex)\r
+ {\r
+ return "UserEnumerableExt1";\r
+ }\r
+\r
+ public static string UserQueryableExt2<T> (this IEnumerable<T> e, Func<int, int> ex)\r
+ {\r
+ return "UserEnumerableExt2";\r
+ }\r
+\r
+ public static string NonGenericMethod (this IQueryable<int> iq) \r
+ {\r
+ return "QueryableNonGenericMethod";\r
+ }\r
+\r
+ public static string NonGenericMethod (this IEnumerable<int> iq) \r
+ {\r
+ return "EnumerableNonGenericMethod";\r
+ }\r
+\r
+ public static string InstantiatedGenericMethod<T> (this IQueryable<int> iq, T t) \r
+ {\r
+ return "QueryableInstantiatedGenericMethod";\r
+ }\r
+\r
+ public static string InstantiatedGenericMethod (this IEnumerable<int> ie, int t) \r
+ {\r
+ return "EnumerableInstantiatedGenericMethod";\r
+ }\r
+ }\r
+}\r