Skip to content

Commit cb67239

Browse files
committed
2 parents 8f4ff3e + e20eff1 commit cb67239

File tree

16 files changed

+173
-146
lines changed

16 files changed

+173
-146
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
using System.Collections;
2+
using NHibernate.Util;
3+
using NUnit.Framework;
4+
5+
namespace NHibernate.Test.NHSpecificTest.NH3964
6+
{
7+
[TestFixture]
8+
public class Fixture
9+
{
10+
[Test(Description = "Test for removal of a workaround for an old Fx bug (<v4)")]
11+
public void AddingNullToNonGenericListShouldNotThrow()
12+
{
13+
var a1 = new ArrayList { null };
14+
var a2 = new ArrayList();
15+
Assert.DoesNotThrow(() => ArrayHelper.AddAll(a2, a1));
16+
}
17+
}
18+
}

src/NHibernate.Test/NHibernate.Test.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@
744744
<Compile Include="NHSpecificTest\NH3961\DateParametersComparedTo.cs" />
745745
<Compile Include="NHSpecificTest\NH3963\Entity.cs" />
746746
<Compile Include="NHSpecificTest\NH3963\MappedAsFixture.cs" />
747+
<Compile Include="NHSpecificTest\NH3964\Fixture.cs" />
747748
<Compile Include="NHSpecificTest\NH3950\Entity.cs" />
748749
<Compile Include="NHSpecificTest\NH3950\Fixture.cs" />
749750
<Compile Include="NHSpecificTest\NH3952\Entity.cs" />

src/NHibernate/Bytecode/EmitUtil.cs

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
using System.Reflection;
33
using System.Reflection.Emit;
44
using System.Collections.Generic;
5+
using NHibernate.Linq;
6+
using NHibernate.Util;
57

68
namespace NHibernate.Bytecode
79
{
@@ -185,28 +187,24 @@ public static System.Type DefineDelegateType(
185187
public static void EmitLoadType(ILGenerator il, System.Type type)
186188
{
187189
il.Emit(OpCodes.Ldtoken, type);
188-
il.Emit(OpCodes.Call, typeof(System.Type).GetMethod("GetTypeFromHandle"));
190+
il.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle);
189191
}
190192

191193
public static void EmitLoadMethodInfo(ILGenerator il, MethodInfo methodInfo)
192194
{
193195
il.Emit(OpCodes.Ldtoken, methodInfo);
194-
il.Emit(
195-
OpCodes.Call,
196-
typeof(MethodBase).GetMethod(
197-
"GetMethodFromHandle", new System.Type[] {typeof(RuntimeMethodHandle)}));
196+
il.Emit(OpCodes.Call, ReflectionCache.MethodBaseMethods.GetMethodFromHandle);
198197
il.Emit(OpCodes.Castclass, typeof(MethodInfo));
199198
}
200199

200+
private static readonly MethodInfo CreateDelegate = ReflectionHelper.GetMethod(
201+
() => Delegate.CreateDelegate(null, null));
202+
201203
public static void EmitCreateDelegateInstance(ILGenerator il, System.Type delegateType, MethodInfo methodInfo)
202204
{
203-
MethodInfo createDelegate = typeof(Delegate).GetMethod(
204-
"CreateDelegate", BindingFlags.Static | BindingFlags.Public | BindingFlags.ExactBinding, null,
205-
new System.Type[] {typeof(System.Type), typeof(MethodInfo)}, null);
206-
207205
EmitLoadType(il, delegateType);
208206
EmitLoadMethodInfo(il, methodInfo);
209-
il.EmitCall(OpCodes.Call, createDelegate, null);
207+
il.EmitCall(OpCodes.Call, CreateDelegate, null);
210208
il.Emit(OpCodes.Castclass, delegateType);
211209
}
212210
}

src/NHibernate/Bytecode/Lightweight/ReflectionOptimizer.cs

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
using System.Reflection.Emit;
33
using System.Security;
44
using System.Security.Permissions;
5+
using NHibernate.Linq;
56
using NHibernate.Properties;
67
using NHibernate.Util;
78

@@ -118,6 +119,9 @@ private static void EmitCastToReference(ILGenerator il, System.Type type)
118119
}
119120
}
120121

122+
private static readonly MethodInfo GetterCallbackInvoke = ReflectionHelper.GetMethod<GetterCallback>(
123+
g => g.Invoke(null, 0));
124+
121125
/// <summary>
122126
/// Generates a dynamic method on the given type.
123127
/// </summary>
@@ -163,8 +167,7 @@ private GetPropertyValuesInvoker GenerateGetPropertyValuesMethod(IGetter[] gette
163167
else
164168
{
165169
// using the getter itself via a callback
166-
MethodInfo invokeMethod = typeof (GetterCallback).GetMethod("Invoke",
167-
new[] {typeof (object), typeof (int)});
170+
MethodInfo invokeMethod = GetterCallbackInvoke;
168171
il.Emit(OpCodes.Ldarg_1);
169172
il.Emit(OpCodes.Ldarg_0);
170173
il.Emit(OpCodes.Ldc_I4, i);
@@ -182,6 +185,9 @@ private GetPropertyValuesInvoker GenerateGetPropertyValuesMethod(IGetter[] gette
182185
return (GetPropertyValuesInvoker) method.CreateDelegate(typeof (GetPropertyValuesInvoker));
183186
}
184187

188+
private static readonly MethodInfo SetterCallbackInvoke = ReflectionHelper.GetMethod<SetterCallback>(
189+
g => g.Invoke(null, 0, null));
190+
185191
/// <summary>
186192
/// Generates a dynamic method on the given type.
187193
/// </summary>
@@ -224,8 +230,7 @@ private SetPropertyValuesInvoker GenerateSetPropertyValuesMethod(ISetter[] sette
224230
else
225231
{
226232
// using the setter itself via a callback
227-
MethodInfo invokeMethod = typeof (SetterCallback).GetMethod("Invoke",
228-
new[] {typeof (object), typeof (int), typeof (object)});
233+
MethodInfo invokeMethod = SetterCallbackInvoke;
229234
il.Emit(OpCodes.Ldarg_2);
230235
il.Emit(OpCodes.Ldarg_0);
231236
il.Emit(OpCodes.Ldc_I4, i);

src/NHibernate/Linq/DefaultQueryProvider.cs

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,13 @@ protected virtual NhLinqExpression PrepareQuery(Expression expression, out IQuer
7979
return nhLinqExpression;
8080
}
8181

82+
private static readonly MethodInfo Future = ReflectionHelper.GetMethodDefinition<IQuery>(q => q.Future<object>());
83+
private static readonly MethodInfo FutureValue = ReflectionHelper.GetMethodDefinition<IQuery>(q => q.FutureValue<object>());
84+
8285
protected virtual object ExecuteFutureQuery(NhLinqExpression nhLinqExpression, IQuery query, NhLinqExpression nhQuery)
8386
{
84-
MethodInfo method;
85-
if (nhLinqExpression.ReturnType == NhLinqExpressionReturnType.Sequence)
86-
{
87-
method = typeof (IQuery).GetMethod("Future").MakeGenericMethod(nhQuery.Type);
88-
}
89-
else
90-
{
91-
method = typeof (IQuery).GetMethod("FutureValue").MakeGenericMethod(nhQuery.Type);
92-
}
87+
var method = (nhLinqExpression.ReturnType == NhLinqExpressionReturnType.Sequence ? Future : FutureValue)
88+
.MakeGenericMethod(nhQuery.Type);
9389

9490
object result = method.Invoke(query, new object[0]);
9591

src/NHibernate/Linq/NhRelinqQueryParser.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,26 @@ public NHibernateNodeTypeProvider()
7272
{
7373
var methodInfoRegistry = new MethodInfoBasedNodeTypeRegistry();
7474

75-
methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("Fetch") }, typeof(FetchOneExpressionNode));
76-
methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("FetchMany") }, typeof(FetchManyExpressionNode));
77-
methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("ThenFetch") }, typeof(ThenFetchOneExpressionNode));
78-
methodInfoRegistry.Register(new[] { typeof(EagerFetchingExtensionMethods).GetMethod("ThenFetchMany") }, typeof(ThenFetchManyExpressionNode));
75+
methodInfoRegistry.Register(
76+
new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.Fetch<object, object>(null, null)) },
77+
typeof(FetchOneExpressionNode));
78+
methodInfoRegistry.Register(
79+
new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.FetchMany<object, object>(null, null)) },
80+
typeof(FetchManyExpressionNode));
81+
methodInfoRegistry.Register(
82+
new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.ThenFetch<object, object, object>(null, null)) },
83+
typeof(ThenFetchOneExpressionNode));
84+
methodInfoRegistry.Register(
85+
new[] { ReflectionHelper.GetMethodDefinition(() => EagerFetchingExtensionMethods.ThenFetchMany<object, object, object>(null, null)) },
86+
typeof(ThenFetchManyExpressionNode));
7987

8088
methodInfoRegistry.Register(
8189
new[]
82-
{
83-
typeof(LinqExtensionMethods).GetMethod("Cacheable"),
84-
typeof(LinqExtensionMethods).GetMethod("CacheMode"),
85-
typeof(LinqExtensionMethods).GetMethod("CacheRegion"),
86-
}, typeof(CacheableExpressionNode));
90+
{
91+
ReflectionHelper.GetMethodDefinition(() => LinqExtensionMethods.Cacheable<object>(null)),
92+
ReflectionHelper.GetMethodDefinition(() => LinqExtensionMethods.CacheMode<object>(null, CacheMode.Normal)),
93+
ReflectionHelper.GetMethodDefinition(() => LinqExtensionMethods.CacheRegion<object>(null, null)),
94+
}, typeof(CacheableExpressionNode));
8795

8896
methodInfoRegistry.Register(
8997
new[]

src/NHibernate/Linq/Visitors/ExpressionParameterVisitor.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,19 @@ public class ExpressionParameterVisitor : ExpressionTreeVisitor
1818
private readonly Dictionary<ConstantExpression, NamedParameter> _parameters = new Dictionary<ConstantExpression, NamedParameter>();
1919
private readonly ISessionFactoryImplementor _sessionFactory;
2020

21+
private static readonly MethodInfo QueryableSkipDefinition =
22+
ReflectionHelper.GetMethodDefinition(() => Queryable.Skip<object>(null, 0));
23+
private static readonly MethodInfo QueryableTakeDefinition =
24+
ReflectionHelper.GetMethodDefinition(() => Queryable.Take<object>(null, 0));
25+
private static readonly MethodInfo EnumerableSkipDefinition =
26+
ReflectionHelper.GetMethodDefinition(() => Enumerable.Skip<object>(null, 0));
27+
private static readonly MethodInfo EnumerableTakeDefinition =
28+
ReflectionHelper.GetMethodDefinition(() => Enumerable.Take<object>(null, 0));
29+
2130
private readonly ICollection<MethodBase> _pagingMethods = new HashSet<MethodBase>
2231
{
23-
ReflectionHelper.GetMethodDefinition(() => Queryable.Skip<object>(null, 0)),
24-
ReflectionHelper.GetMethodDefinition(() => Queryable.Take<object>(null, 0)),
25-
ReflectionHelper.GetMethodDefinition(() => Enumerable.Skip<object>(null, 0)),
26-
ReflectionHelper.GetMethodDefinition(() => Enumerable.Take<object>(null, 0)),
32+
QueryableSkipDefinition, QueryableTakeDefinition,
33+
EnumerableSkipDefinition, EnumerableTakeDefinition
2734
};
2835

2936
public ExpressionParameterVisitor(ISessionFactoryImplementor sessionFactory)
Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
using System.Linq;
2+
using System.Reflection;
23
using Remotion.Linq.Clauses.ResultOperators;
34

45
namespace NHibernate.Linq.Visitors.ResultOperatorProcessors
56
{
6-
public class ProcessFirst : ProcessFirstOrSingleBase, IResultOperatorProcessor<FirstResultOperator>
7-
{
8-
public void Process(FirstResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
9-
{
10-
var firstMethod = resultOperator.ReturnDefaultWhenEmpty
11-
? ReflectionHelper.GetMethodDefinition(() => Queryable.FirstOrDefault<object>(null))
12-
: ReflectionHelper.GetMethodDefinition(() => Queryable.First<object>(null));
7+
public class ProcessFirst : ProcessFirstOrSingleBase, IResultOperatorProcessor<FirstResultOperator>
8+
{
9+
private static readonly MethodInfo FirstOrDefault =
10+
ReflectionHelper.GetMethodDefinition(() => Queryable.FirstOrDefault<object>(null));
11+
private static readonly MethodInfo First =
12+
ReflectionHelper.GetMethodDefinition(() => Queryable.First<object>(null));
1313

14-
AddClientSideEval(firstMethod, queryModelVisitor, tree);
14+
public void Process(FirstResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
15+
{
16+
var firstMethod = resultOperator.ReturnDefaultWhenEmpty ? FirstOrDefault : First;
1517

16-
tree.AddTakeClause(tree.TreeBuilder.Constant(1));
17-
}
18-
}
18+
AddClientSideEval(firstMethod, queryModelVisitor, tree);
19+
20+
tree.AddTakeClause(tree.TreeBuilder.Constant(1));
21+
}
22+
}
1923
}
Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
using System.Linq;
2+
using System.Reflection;
23
using Remotion.Linq.Clauses.ResultOperators;
34

45
namespace NHibernate.Linq.Visitors.ResultOperatorProcessors
56
{
6-
public class ProcessSingle : ProcessFirstOrSingleBase, IResultOperatorProcessor<SingleResultOperator>
7-
{
8-
public void Process(SingleResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
9-
{
10-
var firstMethod = resultOperator.ReturnDefaultWhenEmpty
11-
? ReflectionHelper.GetMethodDefinition(() => Queryable.SingleOrDefault<object>(null))
12-
: ReflectionHelper.GetMethodDefinition(() => Queryable.Single<object>(null));
7+
public class ProcessSingle : ProcessFirstOrSingleBase, IResultOperatorProcessor<SingleResultOperator>
8+
{
9+
private static readonly MethodInfo SingleOrDefault =
10+
ReflectionHelper.GetMethodDefinition(() => Queryable.SingleOrDefault<object>(null));
11+
private static readonly MethodInfo Single =
12+
ReflectionHelper.GetMethodDefinition(() => Queryable.Single<object>(null));
1313

14-
AddClientSideEval(firstMethod, queryModelVisitor, tree);
15-
}
16-
}
14+
public void Process(SingleResultOperator resultOperator, QueryModelVisitor queryModelVisitor, IntermediateHqlTree tree)
15+
{
16+
var firstMethod = resultOperator.ReturnDefaultWhenEmpty ? SingleOrDefault : Single;
17+
18+
AddClientSideEval(firstMethod, queryModelVisitor, tree);
19+
}
20+
}
1721
}

src/NHibernate/Proxy/DynamicProxy/DefaultMethodEmitter.cs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,18 @@
1010
using System.Diagnostics;
1111
using System.Reflection;
1212
using System.Reflection.Emit;
13+
using NHibernate.Linq;
14+
using NHibernate.Util;
1315

1416
namespace NHibernate.Proxy.DynamicProxy
1517
{
1618
internal class DefaultMethodEmitter : IMethodBodyEmitter
1719
{
1820
private static readonly MethodInfo getInterceptor;
1921

20-
private static readonly MethodInfo getGenericMethodFromHandle = typeof (MethodBase).GetMethod("GetMethodFromHandle",
21-
BindingFlags.Public | BindingFlags.Static, null,
22-
new[] {typeof (RuntimeMethodHandle), typeof (RuntimeTypeHandle)}, null);
23-
24-
private static readonly MethodInfo getMethodFromHandle = typeof (MethodBase).GetMethod("GetMethodFromHandle", new[] {typeof (RuntimeMethodHandle)});
25-
private static readonly MethodInfo getTypeFromHandle = typeof(System.Type).GetMethod("GetTypeFromHandle");
26-
private static readonly MethodInfo handlerMethod = typeof (IInterceptor).GetMethod("Intercept");
22+
private static readonly MethodInfo handlerMethod = ReflectionHelper.GetMethod<IInterceptor>(
23+
i => i.Intercept(null));
24+
private static readonly MethodInfo getArguments = typeof(InvocationInfo).GetMethod("get_Arguments");
2725

2826
private static readonly ConstructorInfo infoConstructor = typeof (InvocationInfo).GetConstructor(new[]
2927
{
@@ -118,7 +116,6 @@ private static void EmitBaseMethodCall(ILGenerator IL, MethodInfo method)
118116
private static void SaveRefArguments(ILGenerator IL, ParameterInfo[] parameters)
119117
{
120118
// Save the arguments returned from the handler method
121-
MethodInfo getArguments = typeof (InvocationInfo).GetMethod("get_Arguments");
122119
IL.Emit(OpCodes.Ldloc_1);
123120
IL.Emit(OpCodes.Call, getArguments);
124121
IL.Emit(OpCodes.Stloc_0);
@@ -192,11 +189,11 @@ private static void PushTargetMethodInfo(ILGenerator IL, MethodBuilder generated
192189
if (declaringType.IsGenericType)
193190
{
194191
IL.Emit(OpCodes.Ldtoken, declaringType);
195-
IL.Emit(OpCodes.Call, getGenericMethodFromHandle);
192+
IL.Emit(OpCodes.Call, ReflectionCache.MethodBaseMethods.GetMethodFromHandleWithDeclaringType);
196193
}
197194
else
198195
{
199-
IL.Emit(OpCodes.Call, getMethodFromHandle);
196+
IL.Emit(OpCodes.Call, ReflectionCache.MethodBaseMethods.GetMethodFromHandle);
200197
}
201198

202199
IL.Emit(OpCodes.Castclass, typeof(MethodInfo));
@@ -232,7 +229,7 @@ private void PushGenericArguments(MethodInfo method, ILGenerator IL)
232229
IL.Emit(OpCodes.Dup);
233230
IL.Emit(OpCodes.Ldc_I4, index);
234231
IL.Emit(OpCodes.Ldtoken, currentType);
235-
IL.Emit(OpCodes.Call, getTypeFromHandle);
232+
IL.Emit(OpCodes.Call, ReflectionCache.TypeMethods.GetTypeFromHandle);
236233
IL.Emit(OpCodes.Stelem_Ref);
237234
}
238235
}

0 commit comments

Comments
 (0)