Skip to content

Commit b19d098

Browse files
committed
Handling of interface members in ConstructorExpression translation
1 parent e046614 commit b19d098

File tree

3 files changed

+55
-24
lines changed

3 files changed

+55
-24
lines changed

Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs

Lines changed: 43 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,33 +1228,36 @@ protected override Expression VisitMemberInit(MemberInitExpression mi)
12281228
/// <exception cref="InvalidOperationException"><c>InvalidOperationException</c>.</exception>
12291229
private Expression GetMember(Expression expression, MemberInfo member, Expression sourceExpression)
12301230
{
1231-
if (expression==null)
1231+
if (expression == null) {
12321232
return null;
1233+
}
12331234

1234-
MarkerType markerType;
12351235
expression = expression.StripCasts();
1236-
bool isMarker = expression.TryGetMarker(out markerType);
1236+
var isMarker = expression.TryGetMarker(out var markerType);
12371237
expression = expression.StripMarkers();
12381238
expression = expression.StripCasts();
12391239

12401240
if (expression.IsAnonymousConstructor()) {
12411241
var newExpression = (NewExpression) expression;
1242-
int memberIndex = newExpression.Members.IndexOf(member);
1242+
var memberIndex = newExpression.Members.IndexOf(member);
12431243
if (memberIndex < 0)
12441244
throw new InvalidOperationException(string.Format(Strings.ExCouldNotGetMemberXFromExpression, member));
12451245
var argument = Visit(newExpression.Arguments[memberIndex]);
12461246
return isMarker ? new MarkerExpression(argument, markerType) : argument;
12471247
}
12481248

12491249
var extendedExpression = expression as ExtendedExpression;
1250-
if (extendedExpression==null)
1250+
if (extendedExpression == null) {
12511251
return IsConditionalOrWellknown(expression)
12521252
? GetConditionalMember(expression, member, sourceExpression)
12531253
: null;
1254+
}
12541255

12551256
Expression result = null;
1256-
Func<PersistentFieldExpression, bool> propertyFilter
1257-
= f => f.Name==context.Domain.Handlers.NameBuilder.BuildFieldName((PropertyInfo) member);
1257+
bool propertyFilter(PersistentFieldExpression f)
1258+
{
1259+
return f.Name == context.Domain.Handlers.NameBuilder.BuildFieldName((PropertyInfo) member);
1260+
}
12581261

12591262
switch (extendedExpression.ExtendedType) {
12601263
case ExtendedExpressionType.FullText:
@@ -1266,22 +1269,36 @@ Func<PersistentFieldExpression, bool> propertyFilter
12661269
}
12671270
break;
12681271
case ExtendedExpressionType.Grouping:
1269-
if (member.Name=="Key")
1272+
if (member.Name == "Key") {
12701273
return ((GroupingExpression) expression).KeyExpression;
1274+
}
12711275
break;
12721276
case ExtendedExpressionType.Constructor:
1273-
var bindings = ((ConstructorExpression) extendedExpression).Bindings;
1274-
// only make sure that type has needed member
1275-
if (!bindings.TryGetValue(member, out result)) {
1276-
// Key in bindings might be a property/field reflected from a base type
1277-
// but our member might be reflected from child type.
1278-
var baseMember = member.DeclaringType.GetMember(member.Name).FirstOrDefault();
1279-
if (baseMember==null)
1280-
throw new InvalidOperationException(string.Format(
1281-
Strings.ExMemberXOfTypeYIsNotInitializedCheckIfConstructorArgumentIsCorrectOrFieldInitializedThroughInitializer,
1282-
member.Name, member.ReflectedType.Name));
1283-
}
1284-
result = Visit(result);
1277+
var nativeExpression = ((ConstructorExpression) extendedExpression);
1278+
var bindings = nativeExpression.Bindings;
1279+
// only make sure that type has needed member
1280+
if (!bindings.TryGetValue(member, out result)) {
1281+
// Key in bindings might be a property/field reflected from a base type
1282+
// but our member might be reflected from child type.
1283+
var baseType = member.DeclaringType;
1284+
if (baseType.IsInterface) {
1285+
var implementor = member.GetImplementation(nativeExpression.Type);
1286+
if (implementor == null) {
1287+
throw new InvalidOperationException(string.Format(Strings.ExThereIsNoImplemetationOfXYMemberInZType,
1288+
member.DeclaringType.Name, member.Name, nativeExpression.Type.ToString()));
1289+
}
1290+
_ = bindings.TryGetValue(implementor, out result);
1291+
}
1292+
else {
1293+
var baseMember = baseType.GetMember(member.Name).FirstOrDefault();
1294+
if (baseMember == null) {
1295+
throw new InvalidOperationException(string.Format(
1296+
Strings.ExMemberXOfTypeYIsNotInitializedCheckIfConstructorArgumentIsCorrectOrFieldInitializedThroughInitializer,
1297+
member.Name, member.ReflectedType.Name));
1298+
}
1299+
}
1300+
}
1301+
result = Visit(result);
12851302
break;
12861303
case ExtendedExpressionType.Structure:
12871304
case ExtendedExpressionType.StructureField:
@@ -1295,21 +1312,23 @@ Func<PersistentFieldExpression, bool> propertyFilter
12951312
case ExtendedExpressionType.Entity:
12961313
var entityExpression = (EntityExpression) expression;
12971314
result = entityExpression.Fields.FirstOrDefault(propertyFilter);
1298-
if (result==null) {
1315+
if (result == null) {
12991316
EnsureEntityFieldsAreJoined(entityExpression);
13001317
result = entityExpression.Fields.First(propertyFilter);
13011318
}
13021319
break;
13031320
case ExtendedExpressionType.Field:
1304-
if (isMarker && ((markerType & MarkerType.Single)==MarkerType.Single))
1321+
if (isMarker && ((markerType & MarkerType.Single) == MarkerType.Single)) {
13051322
throw new InvalidOperationException(string.Format(Strings.ExUseMethodXOnFirstInsteadOfSingle, sourceExpression.ToString(true), member.Name));
1306-
if (member.DeclaringType.IsGenericType && member.DeclaringType.GetGenericTypeDefinition()==typeof (Nullable<>))
1323+
}
1324+
if (member.DeclaringType.IsGenericType && member.DeclaringType.GetGenericTypeDefinition() == typeof(Nullable<>)) {
13071325
expression = Expression.Convert(expression, member.DeclaringType);
1326+
}
13081327
return Expression.MakeMemberAccess(expression, member);
13091328
case ExtendedExpressionType.EntityField:
13101329
var entityFieldExpression = (EntityFieldExpression) expression;
13111330
result = entityFieldExpression.Fields.FirstOrDefault(propertyFilter);
1312-
if (result==null) {
1331+
if (result == null) {
13131332
EnsureEntityReferenceIsJoined(entityFieldExpression);
13141333
result = entityFieldExpression.Entity.Fields.First(propertyFilter);
13151334
}

Orm/Xtensive.Orm/Strings.Designer.cs

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Orm/Xtensive.Orm/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3449,4 +3449,7 @@ Error: {1}</value>
34493449
<data name="ExCannotApplyNodeConfigurationSettingsConnectionIsInUse" xml:space="preserve">
34503450
<value>Cannot apply node configuration: connection is already in use. This may happen if the session was open asynchronously. Use new StorageNode.OpenSession(...) API instead of Session.SelectStorageNode(...)</value>
34513451
</data>
3452+
<data name="ExThereIsNoImplemetationOfXYMemberInZType" xml:space="preserve">
3453+
<value>There is no implemetation of '{0}.{1}' member in '{0}' type.</value>
3454+
</data>
34523455
</root>

0 commit comments

Comments
 (0)