Add implementation for AsQueryable.
authorRoei Erez <roeie@mono-cvs.ximian.com>
Thu, 15 May 2008 12:36:13 +0000 (12:36 -0000)
committerRoei Erez <roeie@mono-cvs.ximian.com>
Thu, 15 May 2008 12:36:13 +0000 (12:36 -0000)
svn path=/trunk/mcs/; revision=103265

15 files changed:
mcs/class/System.Core/System.Core-2008.JavaEE.csproj
mcs/class/System.Core/System.Core-2008.csproj
mcs/class/System.Core/System.Core-2008.sln
mcs/class/System.Core/System.Core.dll.sources
mcs/class/System.Core/System.Core_test.dll.sources
mcs/class/System.Core/System.Linq.Expressions/ChangeLog
mcs/class/System.Core/System.Linq.Expressions/ExpressionTransformer.cs [new file with mode: 0644]
mcs/class/System.Core/System.Linq/ChangeLog
mcs/class/System.Core/System.Linq/Queryable.cs
mcs/class/System.Core/System.Linq/QueryableEnumerable.cs [new file with mode: 0644]
mcs/class/System.Core/System.Linq/QueryableTransformer.cs [new file with mode: 0644]
mcs/class/System.Core/Test/System.Core.Tests-2008.JavaEE.csproj
mcs/class/System.Core/Test/System.Core.Tests-2008.csproj
mcs/class/System.Core/Test/System.Linq/ChangeLog
mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs [new file with mode: 0644]

index 776b54e8763935aa96fc7b23f268da7f7d2fdc6f..a4a7919fa6e652dd307d6ef79067aa3cd013a34e 100644 (file)
     <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
index 4f1cf58f6537102aa7a8675fbe1c3ab386df1c44..ee9f8c07c23146fc02dc1ea51889569ab4d12d72 100755 (executable)
@@ -53,6 +53,7 @@
     <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
@@ -74,6 +75,8 @@
     <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
index bce8a7e8f32c1c8aefad9d832687dc782d52509d..35a64066e0b423ce73daae1ebcd8d0f107f46a09 100755 (executable)
@@ -1,10 +1,18 @@
 \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
@@ -24,6 +32,12 @@ Global
                {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
index fbd78daa6ba058cad4139e2b562fe5571ccc5842..2f3171fcbd6d193ef0296e4b1c5c92d0ec5b222c 100644 (file)
@@ -15,6 +15,8 @@ System.Runtime.CompilerServices/IStrongBox.cs
 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
@@ -42,6 +44,7 @@ System.Linq.Expressions/Expression_T.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
index 2f6fc57be49b1ba57035aa85ab68ccad20046c06..9046e242ed9800645c4cc6024e44a3cc4adda83f 100644 (file)
@@ -4,6 +4,7 @@ System/TimeZoneInfo.TransitionTimeTest.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
index 27275f180b944a6fb23b9e2377ae186bd2f9c1f4..258832a4eea8ddb56ad5baf4731b035e9e368e2e 100644 (file)
@@ -1,3 +1,8 @@
+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
diff --git a/mcs/class/System.Core/System.Linq.Expressions/ExpressionTransformer.cs b/mcs/class/System.Core/System.Linq.Expressions/ExpressionTransformer.cs
new file mode 100644 (file)
index 0000000..f82a1f6
--- /dev/null
@@ -0,0 +1,321 @@
+//\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
index b20e6b9f0761ab5419d0851df8ab541b1750d75c..7bddb18e3dde9ce80f0d1b46c271a74c59c10423 100644 (file)
@@ -1,3 +1,9 @@
+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
index 3daf0e05303d8741f8345680ccf75e62d03245b2..dd08ebe241d18bb8f570a92e40f1637897e91e33 100644 (file)
@@ -144,7 +144,7 @@ namespace System.Linq {
                        if (queryable != null)
                                return queryable;
 
-                       throw new NotImplementedException ();
+                       return new QueryableEnumerable<TElement> (new ConstantExpression (source, typeof (IQueryable<TElement>)));
                }
 
                [MonoTODO]
diff --git a/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs b/mcs/class/System.Core/System.Linq/QueryableEnumerable.cs
new file mode 100644 (file)
index 0000000..4707803
--- /dev/null
@@ -0,0 +1,94 @@
+//\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
diff --git a/mcs/class/System.Core/System.Linq/QueryableTransformer.cs b/mcs/class/System.Core/System.Linq/QueryableTransformer.cs
new file mode 100644 (file)
index 0000000..d0aaf77
--- /dev/null
@@ -0,0 +1,172 @@
+//\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
index 5a58919298bc3840eb02e794bfb09ebbc1582bc9..d8945b06e3c04dc66edc326383d5c0d31b55656b 100644 (file)
   -->\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
index e592341572fb311c00c5502c706e5f3068c8851f..01c228b99cfc977fab4fcae272668d8a8fd22262 100755 (executable)
     <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
index 97894bcf3629a6c2705c9b00299721166c37db3c..d0728314d09398e222f4c4a036a495c1bf3844f1 100644 (file)
@@ -1,3 +1,7 @@
+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.
diff --git a/mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs b/mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs
new file mode 100644 (file)
index 0000000..9740f7b
--- /dev/null
@@ -0,0 +1,468 @@
+//\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