Skip to content

Commit 7f2a64c

Browse files
committed
CSHARP-5572: Minor refactoring.
1 parent 8f4b081 commit 7f2a64c

File tree

11 files changed

+99
-120
lines changed

11 files changed

+99
-120
lines changed

src/MongoDB.Bson/Serialization/Serializers/CharSerializer.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@ namespace MongoDB.Bson.Serialization.Serializers
2222
/// </summary>
2323
public sealed class CharSerializer : StructSerializerBase<char>, IRepresentationConfigurable<CharSerializer>
2424
{
25+
#region static
26+
private static readonly CharSerializer __instance = new();
27+
28+
/// <summary>
29+
/// Returns the default instance of CharSerializer.
30+
/// </summary>
31+
public static CharSerializer Instance => __instance;
32+
#endregion
33+
2534
// private fields
2635
private readonly BsonType _representation;
2736

src/MongoDB.Driver/Linq/Linq3Implementation/KnownSerializerFinders/KnownSerializerFinder.cs

Lines changed: 1 addition & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -14,46 +14,12 @@
1414
*/
1515

1616
using System.Linq.Expressions;
17-
using MongoDB.Bson.Serialization;
1817

1918
namespace MongoDB.Driver.Linq.Linq3Implementation.KnownSerializerFinders;
2019

2120
internal static class KnownSerializerFinder
2221
{
23-
public static KnownSerializerMap FindKnownSerializers(
24-
Expression expression,
25-
ExpressionTranslationOptions translationOptions)
26-
{
27-
var knownSerializers = new KnownSerializerMap();
28-
return FindKnownSerializers(expression, translationOptions, knownSerializers);
29-
}
30-
31-
public static KnownSerializerMap FindKnownSerializers(
32-
Expression expression,
33-
ExpressionTranslationOptions translationOptions,
34-
Expression initialNode,
35-
IBsonSerializer knownSerializer)
36-
{
37-
var knownSerializers = new KnownSerializerMap();
38-
knownSerializers.AddSerializer(initialNode, knownSerializer);
39-
return FindKnownSerializers(expression, translationOptions, knownSerializers);
40-
}
41-
42-
public static KnownSerializerMap FindKnownSerializers(
43-
Expression expression,
44-
ExpressionTranslationOptions translationOptions,
45-
(Expression Node, IBsonSerializer KnownSerializer)[] initialNodes)
46-
{
47-
var knownSerializers = new KnownSerializerMap();
48-
foreach (var (initialNode, knownSerializer) in initialNodes)
49-
{
50-
knownSerializers.AddSerializer(initialNode, knownSerializer);
51-
52-
}
53-
return FindKnownSerializers(expression, translationOptions, knownSerializers);
54-
}
55-
56-
public static KnownSerializerMap FindKnownSerializers(
22+
public static void FindKnownSerializers(
5723
Expression expression,
5824
ExpressionTranslationOptions translationOptions,
5925
KnownSerializerMap knownSerializers)
@@ -75,7 +41,5 @@ public static KnownSerializerMap FindKnownSerializers(
7541
throw new ExpressionNotSupportedException(expressionWithUnknownSerializer, because: "we were unable to determine which serializer to use for the result");
7642
}
7743
//#endif
78-
79-
return knownSerializers;
8044
}
8145
}

src/MongoDB.Driver/Linq/Linq3Implementation/KnownSerializerFinders/KnownSerializerFinderHelperMethods.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,14 @@ private void DeduceBooleanSerializer(Expression node)
146146
}
147147
}
148148

149+
private void DeduceCharSerializer(Expression node)
150+
{
151+
if (IsNotKnown(node))
152+
{
153+
AddKnownSerializer(node, CharSerializer.Instance);
154+
}
155+
}
156+
149157
private void DeduceCollectionAndCollectionSerializers(Expression collectionExpression1, Expression collectionExpression2)
150158
{
151159
if (IsNotKnown(collectionExpression1) && IsKnown(collectionExpression2, out var knownCollectionSerializer2))

src/MongoDB.Driver/Linq/Linq3Implementation/KnownSerializerFinders/KnownSerializerFinderVisitMethodCall.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ void DeduceMethodCallSerializers()
814814
case "Exp": DeduceExpMethodSerializers(); break;
815815
case "Field": DeduceFieldMethodSerializers(); break;
816816
case "get_Item": DeduceGetItemMethodSerializers(); break;
817+
case "get_Chars": DeduceGetCharsMethodSerializers(); break;
817818
case "GroupBy": DeduceGroupByMethodSerializers(); break;
818819
case "GroupJoin": DeduceGroupJoinMethodSerializers(); break;
819820
case "Inject": DeduceInjectMethodSerializers(); break;
@@ -2067,6 +2068,16 @@ bool IsInstanceGetItemMethod(out Expression collectionExpression, out Expression
20672068
}
20682069
}
20692070

2071+
void DeduceGetCharsMethodSerializers()
2072+
{
2073+
if (method.Is(StringMethod.GetChars))
2074+
{
2075+
DeduceCharSerializer(node);
2076+
}
2077+
2078+
DeduceUnknowableSerializer(node);
2079+
}
2080+
20702081
void DeduceGroupByMethodSerializers()
20712082
{
20722083
if (method.IsOneOf(__groupByMethods))

src/MongoDB.Driver/Linq/Linq3Implementation/KnownSerializerFinders/KnownSerializerFinderVisitNew.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
2424
using MongoDB.Driver.Linq.Linq3Implementation.Reflection;
2525
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;
26-
using MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToAggregationExpressionTranslators;
2726

2827
namespace MongoDB.Driver.Linq.Linq3Implementation.KnownSerializerFinders;
2928

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

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313
* limitations under the License.
1414
*/
1515

16+
using System;
1617
using System.Collections.Generic;
18+
using System.Linq;
1719
using System.Linq.Expressions;
20+
using System.Reflection;
1821
using MongoDB.Bson.Serialization;
1922
using MongoDB.Driver.Linq.Linq3Implementation.ExtensionMethods;
2023
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;
@@ -74,6 +77,50 @@ public static IBsonSerializer GetItemSerializer(this IBsonSerializer serializer,
7477
}
7578
}
7679

80+
public static IReadOnlyList<BsonSerializationInfo> GetMatchingMemberSerializationInfosForConstructorParameters(
81+
this IBsonSerializer serializer,
82+
Expression expression,
83+
ConstructorInfo constructorInfo)
84+
{
85+
if (serializer is not IBsonDocumentSerializer documentSerializer)
86+
{
87+
throw new ExpressionNotSupportedException(expression, because: $"serializer type {serializer.GetType().Name} does not implement IBsonDocumentSerializer");
88+
}
89+
90+
var matchingMemberSerializationInfos = new List<BsonSerializationInfo>();
91+
foreach (var constructorParameter in constructorInfo.GetParameters())
92+
{
93+
var matchingMemberSerializationInfo = GetMatchingMemberSerializationInfo(expression, documentSerializer, constructorParameter.Name);
94+
matchingMemberSerializationInfos.Add(matchingMemberSerializationInfo);
95+
}
96+
97+
return matchingMemberSerializationInfos;
98+
99+
static BsonSerializationInfo GetMatchingMemberSerializationInfo(
100+
Expression expression,
101+
IBsonDocumentSerializer documentSerializer,
102+
string constructorParameterName)
103+
{
104+
var possibleMatchingMembers = documentSerializer.ValueType.GetMembers().Where(m => m.Name.Equals(constructorParameterName, StringComparison.OrdinalIgnoreCase)).ToArray();
105+
if (possibleMatchingMembers.Length == 0)
106+
{
107+
throw new ExpressionNotSupportedException(expression, because: $"no matching member found for constructor parameter: {constructorParameterName}");
108+
}
109+
if (possibleMatchingMembers.Length > 1)
110+
{
111+
throw new ExpressionNotSupportedException(expression, because: $"multiple possible matching members found for constructor parameter: {constructorParameterName}");
112+
}
113+
var matchingMemberName = possibleMatchingMembers[0].Name;
114+
115+
if (!documentSerializer.TryGetMemberSerializationInfo(matchingMemberName, out var matchingMemberSerializationInfo))
116+
{
117+
throw new ExpressionNotSupportedException(expression, because: $"serializer of type {documentSerializer.GetType().Name} did not provide serialization info for member {matchingMemberName}");
118+
}
119+
120+
return matchingMemberSerializationInfo;
121+
}
122+
}
123+
77124
public static bool HasNumericRepresentation(this IBsonSerializer serializer)
78125
{
79126
return

src/MongoDB.Driver/Linq/Linq3Implementation/Serializers/IBsonSerializerExtensions.cs

Lines changed: 0 additions & 71 deletions
This file was deleted.

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/ConcatMethodToPipelineTranslator.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using MongoDB.Driver.Linq.Linq3Implementation.ExtensionMethods;
2121
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
2222
using MongoDB.Driver.Linq.Linq3Implementation.Reflection;
23+
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;
2324

2425
namespace MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators
2526
{
@@ -44,7 +45,9 @@ secondProvider.CollectionNamespace is var secondCollectionNamespace &&
4445
secondCollectionNamespace != null)
4546
{
4647
var secondCollectionName = secondCollectionNamespace.CollectionName;
47-
var secondContext = TranslationContext.Create(secondQueryable.Expression, context.TranslationOptions);
48+
var secondCollectionUltimateSource = TranslationContext.GetUltimateSource(secondQueryable.Expression);
49+
var secondCollectionUltimateSourceSerializer = IQueryableSerializer.Create(secondProvider.PipelineInputSerializer);
50+
var secondContext = TranslationContext.Create(secondQueryable.Expression, secondCollectionUltimateSource, secondCollectionUltimateSourceSerializer, context.TranslationOptions);
4851
var secondPipeline = ExpressionToPipelineTranslator.Translate(secondContext, secondQueryable.Expression);
4952
if (secondPipeline.Ast.Stages.Count == 0)
5053
{

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/ExpressionToPipelineTranslators/UnionMethodToPipelineTranslator.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
using MongoDB.Driver.Linq.Linq3Implementation.ExtensionMethods;
2323
using MongoDB.Driver.Linq.Linq3Implementation.Misc;
2424
using MongoDB.Driver.Linq.Linq3Implementation.Reflection;
25+
using MongoDB.Driver.Linq.Linq3Implementation.Serializers;
2526

2627
namespace MongoDB.Driver.Linq.Linq3Implementation.Translators.ExpressionToPipelineTranslators
2728
{
@@ -46,7 +47,9 @@ secondProvider.CollectionNamespace is var secondCollectionNamespace &&
4647
secondCollectionNamespace != null)
4748
{
4849
var secondCollectionName = secondCollectionNamespace.CollectionName;
49-
var secondContext = TranslationContext.Create(expression, context.TranslationOptions);
50+
var secondCollectionUltimateSource = TranslationContext.GetUltimateSource(secondQueryable.Expression);
51+
var secondCollectionUltimateSourceSerializer = IQueryableSerializer.Create(secondProvider.PipelineInputSerializer);
52+
var secondContext = TranslationContext.Create(expression, secondCollectionUltimateSource, secondCollectionUltimateSourceSerializer, context.TranslationOptions);
5053
var secondPipeline = ExpressionToPipelineTranslator.Translate(secondContext, secondQueryable.Expression);
5154
if (secondPipeline.Ast.Stages.Count == 0)
5255
{

src/MongoDB.Driver/Linq/Linq3Implementation/Translators/TranslationContext.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
*/
1515

1616
using System;
17-
using System.CodeDom;
1817
using System.Linq;
1918
using System.Linq.Expressions;
2019
using MongoDB.Bson.Serialization;
@@ -29,14 +28,14 @@ namespace MongoDB.Driver.Linq.Linq3Implementation.Translators
2928
internal class TranslationContext
3029
{
3130
#region static
32-
// TODO: this overload is probably a bug (we probably can't translate an expression if we don't have an initial known node)
3331
public static TranslationContext Create(
34-
Expression expression,
32+
IQueryable queryable,
3533
ExpressionTranslationOptions translationOptions,
3634
TranslationContextData data = null)
3735
{
38-
var knownSerializers = KnownSerializerFinder.FindKnownSerializers(expression, translationOptions);
39-
return Create(translationOptions, knownSerializers, data);
36+
var expression = queryable.Expression;
37+
var provider = (IMongoQueryProviderInternal)queryable.Provider;
38+
return Create(expression, provider, translationOptions, data);
4039
}
4140

4241
public static TranslationContext Create(
@@ -57,7 +56,9 @@ public static TranslationContext Create(
5756
ExpressionTranslationOptions translationOptions,
5857
TranslationContextData data = null)
5958
{
60-
var knownSerializers = KnownSerializerFinder.FindKnownSerializers(expression, translationOptions, initialNode, initialSerializer);
59+
var knownSerializers = new KnownSerializerMap();
60+
knownSerializers.AddSerializer(initialNode, initialSerializer);
61+
KnownSerializerFinder.FindKnownSerializers(expression, translationOptions, knownSerializers);
6162
return Create(translationOptions, knownSerializers, data);
6263
}
6364

@@ -67,7 +68,12 @@ public static TranslationContext Create(
6768
ExpressionTranslationOptions translationOptions,
6869
TranslationContextData data = null)
6970
{
70-
var knownSerializers = KnownSerializerFinder.FindKnownSerializers(expression, translationOptions, initialKnownSerializers);
71+
var knownSerializers = new KnownSerializerMap();
72+
foreach (var (node, serializer) in initialKnownSerializers)
73+
{
74+
knownSerializers.AddSerializer(node, serializer);
75+
}
76+
KnownSerializerFinder.FindKnownSerializers(expression, translationOptions, knownSerializers);
7177
return Create(translationOptions, knownSerializers, data);
7278
}
7379

@@ -81,7 +87,7 @@ public static TranslationContext Create(
8187
return new TranslationContext(translationOptions, knownSerializers, data, symbolTable, nameGenerator);
8288
}
8389

84-
private static Expression GetUltimateSource(Expression expression)
90+
public static Expression GetUltimateSource(Expression expression)
8591
{
8692
if (expression is ConstantExpression constantExpression &&
8793
constantExpression.Value is IQueryable queryable &&

0 commit comments

Comments
 (0)