Skip to content

Commit f0fdba6

Browse files
committed
CSHARP-4708: Support Expression.MakeIndex in LINQ3.
1 parent f25a4c6 commit f0fdba6

File tree

11 files changed

+1006
-130
lines changed

11 files changed

+1006
-130
lines changed

src/MongoDB.Driver/Linq/Linq3Implementation/Misc/TypeExtensions.cs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,21 @@ public static bool Implements(this Type type, Type @interface)
8383
return false;
8484
}
8585

86+
public static bool ImplementsIDictionary(this Type type, out Type keyType, out Type valueType)
87+
{
88+
if (TryGetIDictionaryGenericInterface(type, out var idictionaryType))
89+
{
90+
var genericArguments = idictionaryType.GetGenericArguments();
91+
keyType = genericArguments[0];
92+
valueType = genericArguments[1];
93+
return true;
94+
}
95+
96+
keyType = null;
97+
valueType = null;
98+
return false;
99+
}
100+
86101
public static bool ImplementsIEnumerable(this Type type, out Type itemType)
87102
{
88103
if (TryGetIEnumerableGenericInterface(type, out var ienumerableType))
@@ -102,6 +117,18 @@ public static bool ImplementsIEnumerableOf(this Type type, Type itemType)
102117
actualItemType == itemType;
103118
}
104119

120+
public static bool ImplementsIList(this Type type, out Type itemType)
121+
{
122+
if (TryGetIListGenericInterface(type, out var ilistType))
123+
{
124+
itemType = ilistType.GetGenericArguments()[0];
125+
return true;
126+
}
127+
128+
itemType = null;
129+
return false;
130+
}
131+
105132
public static bool Is(this Type type, Type comparand)
106133
{
107134
if (type == comparand)
@@ -262,5 +289,26 @@ public static bool TryGetIEnumerableGenericInterface(this Type type, out Type ie
262289
ienumerableGenericInterface = null;
263290
return false;
264291
}
292+
293+
public static bool TryGetIListGenericInterface(this Type type, out Type ilistGenericInterface)
294+
{
295+
if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IList<>))
296+
{
297+
ilistGenericInterface = type;
298+
return true;
299+
}
300+
301+
foreach (var interfaceType in type.GetInterfaces())
302+
{
303+
if (interfaceType.IsGenericType && interfaceType.GetGenericTypeDefinition() == typeof(IList<>))
304+
{
305+
ilistGenericInterface = interfaceType;
306+
return true;
307+
}
308+
}
309+
310+
ilistGenericInterface = null;
311+
return false;
312+
}
265313
}
266314
}

src/MongoDB.Driver/Linq/Linq3Implementation/Reflection/BsonValueMethod.cs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,33 @@ static BsonValueMethod()
3131
__getItemWithString = ReflectionInfo.IndexerGet((BsonValue v, string index) => v[index]);
3232
}
3333

34-
// public properties
34+
// public static properties
3535
public static MethodInfo GetItemWithInt => __getItemWithInt;
3636
public static MethodInfo GetItemWithString => __getItemWithString;
37+
38+
// public static methods
39+
public static bool IsGetItemWithIntMethod(MethodInfo method)
40+
{
41+
return
42+
(method.DeclaringType == typeof(BsonValue) || method.DeclaringType.IsSubclassOf(typeof(BsonValue))) &&
43+
!method.IsStatic &&
44+
method.Name == "get_Item" &&
45+
method.GetParameters() is var parameters &&
46+
parameters.Length == 1 &&
47+
parameters[0].ParameterType == typeof(int) &&
48+
method.ReturnType == typeof(BsonValue);
49+
}
50+
51+
public static bool IsGetItemWithStringMethod(MethodInfo method)
52+
{
53+
return
54+
(method.DeclaringType == typeof(BsonValue) || method.DeclaringType.IsSubclassOf(typeof(BsonValue))) &&
55+
!method.IsStatic &&
56+
method.Name == "get_Item" &&
57+
method.GetParameters() is var parameters &&
58+
parameters.Length == 1 &&
59+
parameters[0].ParameterType == typeof(string) &&
60+
method.ReturnType == typeof(BsonValue);
61+
}
3762
}
3863
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Reflection;
17+
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
18+
19+
namespace MongoDB.Driver.Linq.Linq3Implementation.Reflection
20+
{
21+
internal static class IDictionaryMethod
22+
{
23+
// public static methods
24+
public static bool IsGetItemWithStringMethod(MethodInfo method)
25+
{
26+
return
27+
!method.IsStatic &&
28+
method.Name == "get_Item" &&
29+
method.GetParameters() is var parameters &&
30+
parameters.Length == 1 &&
31+
parameters[0].ParameterType == typeof(string) &&
32+
method.DeclaringType.ImplementsIDictionary(out var keyType, out var valueType) &&
33+
keyType == typeof(string) &&
34+
method.ReturnType == valueType;
35+
}
36+
}
37+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Reflection;
17+
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
18+
19+
namespace MongoDB.Driver.Linq.Linq3Implementation.Reflection
20+
{
21+
internal static class IListMethod
22+
{
23+
// public static methods
24+
public static bool IsGetItemWithIntMethod(MethodInfo method)
25+
{
26+
return
27+
!method.IsStatic &&
28+
method.Name == "get_Item" &&
29+
method.GetParameters() is var parameters &&
30+
parameters.Length == 1 &&
31+
parameters[0].ParameterType == typeof(int) &&
32+
method.DeclaringType.ImplementsIList(out var itemType) &&
33+
method.ReturnType == itemType;
34+
}
35+
}
36+
}

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToAggregationExpressionTranslators/ExpressionToAggregationExpressionTranslator.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ public static AggregationExpression Translate(TranslationContext context, Expres
6666
return ConditionalExpressionToAggregationExpressionTranslator.Translate(context, (ConditionalExpression)expression);
6767
case ExpressionType.Constant:
6868
return ConstantExpressionToAggregationExpressionTranslator.Translate(context, (ConstantExpression)expression);
69+
case ExpressionType.Index:
70+
return IndexExpressionToAggregationExpressionTranslator.Translate(context, (IndexExpression)expression);
6971
case ExpressionType.MemberAccess:
7072
return MemberExpressionToAggregationExpressionTranslator.Translate(context, (MemberExpression)expression);
7173
case ExpressionType.MemberInit:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/* Copyright 2010-present MongoDB Inc.
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS,
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
using System.Linq.Expressions;
17+
using MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators.MethodTranslators;
18+
19+
namespace MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators
20+
{
21+
internal static class IndexExpressionToAggregationExpressionTranslator
22+
{
23+
// public static methods
24+
public static AggregationExpression Translate(TranslationContext context, IndexExpression expression)
25+
{
26+
var sourceExpression = expression.Object;
27+
var method = expression.Indexer.GetMethod;
28+
var arguments = expression.Arguments;
29+
return GetItemMethodToAggregationExpressionTranslator.Translate(context, expression, method, sourceExpression, arguments);
30+
}
31+
}
32+
}

0 commit comments

Comments
 (0)