User: xtoff
Date: 2009/11/10 02:08 PM
Added:
/DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/
InterfaceMethodGeneratorBase.cs, MinimialisticMethodGenerator.cs
/DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
GeneratorUtil.cs
Removed:
/DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/
EmptyMethodGenerator.cs
Modified:
/DynamicProxy/trunk/src/Castle.DynamicProxy/
Castle.DynamicProxy-vs2008.csproj
/DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/
ClassProxyTargetContributor.cs, ForwardingMethodGenerator.cs,
InterfaceProxyWithoutTargetContributor.cs, MembersCollector.cs
/DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
BaseProxyGenerator.cs, EventToGenerate.cs, IProxyMethod.cs,
InterfaceMethodGenerator.cs, MethodToGenerate.cs, MethodWithCallbackGenerator.cs
Log:
- removed some dead code, some duplications and cleaned up some more code
File Changes:
Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/
=======================================================
File [modified]: Castle.DynamicProxy-vs2008.csproj
Delta lines: +1 -1
===================================================================
---
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ClassProxyTargetContributor.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ClassProxyTargetContributor.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -143,7 +143,7 @@
}
else
{
- generator = new EmptyMethodGenerator(method,
createMethod);
+ generator = new
MinimialisticMethodGenerator(method, createMethod);
}
var proxyMethod = generator.Generate(@class, options,
namingScope);
Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/
====================================================================
File [modified]: ClassProxyTargetContributor.cs
Delta lines: +8 -42
===================================================================
---
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ForwardingMethodGenerator.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/ForwardingMethodGenerator.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -14,64 +14,30 @@
namespace Castle.DynamicProxy.Contributors
{
- using System.Reflection;
using Castle.DynamicProxy.Generators;
using Castle.DynamicProxy.Generators.Emitters;
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
- public class ForwardingMethodGenerator : MethodGenerator
+ public class ForwardingMethodGenerator : InterfaceMethodGeneratorBase
{
- private readonly MethodToGenerate method;
- private readonly CreateMethodDelegate createMethod;
private readonly GetTargetReferenceDelegate getTargetReference;
- public ForwardingMethodGenerator(MethodToGenerate method,
CreateMethodDelegate createMethod,GetTargetReferenceDelegate getTargetReference)
+ public ForwardingMethodGenerator(MethodToGenerate method,
CreateMethodDelegate createMethod, GetTargetReferenceDelegate
getTargetReference)
+ : base(method, createMethod)
{
- this.method = method;
- this.createMethod = createMethod;
this.getTargetReference = getTargetReference;
}
- public override MethodEmitter Generate(ClassEmitter @class,
ProxyGenerationOptions options, INamingScope namingScope)
+ protected override MethodEmitter
ImplementProxiedMethod(MethodEmitter emitter, ClassEmitter @class,
ProxyGenerationOptions options, INamingScope namingScope)
{
- string name;
- MethodAttributes atts = ObtainMethodAttributes(out
name);
- MethodEmitter methodEmitter = createMethod(name, atts);
- MethodEmitter proxiedMethod =
ImplementProxiedMethod(methodEmitter,
-
@class);
+ emitter.CopyParametersAndReturnTypeFrom(Method.Method,
@class);
+ var targetReference = getTargetReference(@class,
Method.Method);
+ var arguments =
ArgumentsUtil.ConvertToArgumentReferenceExpression(Method.Method.GetParameters());
-
@class.TypeBuilder.DefineMethodOverride(methodEmitter.MethodBuilder,
method.Method);
- return proxiedMethod;
- }
-
- private MethodAttributes ObtainMethodAttributes(out string name)
- {
- var methodInfo = method.Method;
- name = methodInfo.DeclaringType.Name + "." +
methodInfo.Name;
- var attributes = MethodAttributes.Virtual |
- MethodAttributes.Private |
- MethodAttributes.HideBySig |
- MethodAttributes.NewSlot |
- MethodAttributes.Final;
-
- if (method.Standalone == false)
- {
- attributes |= MethodAttributes.SpecialName;
- }
- return attributes;
- }
-
-
- private MethodEmitter ImplementProxiedMethod(MethodEmitter
emitter, ClassEmitter @class)
- {
- emitter.CopyParametersAndReturnTypeFrom(method.Method,
@class);
- var targetReference = getTargetReference(@class,
method.Method);
- var arguments =
ArgumentsUtil.ConvertToArgumentReferenceExpression(method.Method.GetParameters());
-
emitter.CodeBuilder.AddStatement(new ReturnStatement(
new
MethodInvocationExpression(
targetReference,
-
method.Method,
+
Method.Method,
arguments) { VirtualCall = true }));
return emitter;
File [removed]: EmptyMethodGenerator.cs
Delta lines: None
None
File [modified]: ForwardingMethodGenerator.cs
Delta lines: +72 -0
===================================================================
---
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/InterfaceMethodGeneratorBase.cs
(rev 0)
+++
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/InterfaceMethodGeneratorBase.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -0,0 +1,72 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.DynamicProxy.Contributors
+{
+ using System.Diagnostics;
+ using System.Reflection;
+
+ using Castle.DynamicProxy.Generators;
+ using Castle.DynamicProxy.Generators.Emitters;
+
+ public abstract class InterfaceMethodGeneratorBase : MethodGenerator
+ {
+ private readonly MethodToGenerate method;
+
+ protected MethodToGenerate Method
+ {
+ get { return method; }
+ }
+
+ private readonly CreateMethodDelegate createMethod;
+
+ protected InterfaceMethodGeneratorBase(MethodToGenerate method,
CreateMethodDelegate createMethod)
+ {
+ Debug.Assert(method.Method.DeclaringType.IsInterface,
"method.Method.DeclaringType.IsInterface");
+ this.method = method;
+ this.createMethod = createMethod;
+ }
+
+
+ public override MethodEmitter Generate(ClassEmitter @class,
ProxyGenerationOptions options, INamingScope namingScope)
+ {
+ string name;
+ MethodAttributes atts = ObtainMethodAttributes(out
name);
+ MethodEmitter methodEmitter = createMethod(name, atts);
+ MethodEmitter proxiedMethod =
ImplementProxiedMethod(methodEmitter, @class,options,namingScope);
+
+
@class.TypeBuilder.DefineMethodOverride(methodEmitter.MethodBuilder,
method.Method);
+ return proxiedMethod;
+ }
+
+ private MethodAttributes ObtainMethodAttributes(out string name)
+ {
+ var methodInfo = method.Method;
+ name = methodInfo.DeclaringType.Name + "." +
methodInfo.Name;
+ var attributes = MethodAttributes.Virtual |
+ MethodAttributes.Private |
+ MethodAttributes.HideBySig |
+ MethodAttributes.NewSlot |
+ MethodAttributes.Final;
+
+ if (method.Standalone == false)
+ {
+ attributes |= MethodAttributes.SpecialName;
+ }
+ return attributes;
+ }
+
+ protected abstract MethodEmitter
ImplementProxiedMethod(MethodEmitter emitter, ClassEmitter @class,
ProxyGenerationOptions options, INamingScope namingScope);
+ }
+}
File [added]: InterfaceMethodGeneratorBase.cs
Delta lines: +1 -1
===================================================================
---
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/InterfaceProxyWithoutTargetContributor.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++
DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/InterfaceProxyWithoutTargetContributor.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -116,7 +116,7 @@
}
else
{
- generator= new EmptyMethodGenerator(method,
createMethod);
+ generator= new
MinimialisticMethodGenerator(method, createMethod);
}
File [modified]: InterfaceProxyWithoutTargetContributor.cs
Delta lines: +3 -12
===================================================================
--- DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/MembersCollector.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Contributors/MembersCollector.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -19,7 +19,7 @@
using System.Reflection;
using Generators;
- public class MembersCollector
+ public abstract class MembersCollector
{
private const BindingFlags Flags = BindingFlags.Public |
BindingFlags.NonPublic | BindingFlags.Instance;
protected readonly bool onlyProxyVirtual;
@@ -33,7 +33,7 @@
protected readonly ITypeContributor contributor;
- public MembersCollector(Type type, ITypeContributor
contributor, bool onlyProxyVirtual, InterfaceMapping map)
+ protected MembersCollector(Type type, ITypeContributor
contributor, bool onlyProxyVirtual, InterfaceMapping map)
{
this.type = type;
this.contributor = contributor;
@@ -177,17 +177,8 @@
return methodToGenerate;
}
- protected virtual MethodToGenerate
GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool
isStandalone)
- {
- if (!IsAccessible(method))
- {
- return null;
- }
+ protected abstract MethodToGenerate
GetMethodToGenerate(MethodInfo method, IProxyGenerationHook hook, bool
isStandalone);
- var proxyable = AcceptMethod(method, onlyProxyVirtual,
hook);
- return new MethodToGenerate(method, isStandalone,
contributor, GetMethodOnTarget(method),proxyable);
- }
-
protected virtual MethodInfo GetMethodOnTarget(MethodInfo
method)
{
File [modified]: MembersCollector.cs
Delta lines: +0 -26
===================================================================
--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/BaseProxyGenerator.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/BaseProxyGenerator.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -268,32 +268,6 @@
#endregion
- private void ValidateMixinInterfaces(IEnumerable<Type>
interfacesToCheckAgainst, string roleOfCheckedInterfaces)
- {
- foreach (Type interfaceType in interfacesToCheckAgainst)
- {
- ValidateMixinInterface(interfaceType,
roleOfCheckedInterfaces);
- }
- }
-
- private void ValidateMixinInterface(Type interfaceType, string
roleOfCheckedInterface)
- {
- if
(ProxyGenerationOptions.MixinData.ContainsMixin(interfaceType))
- {
- object mixinWithSameInterface =
ProxyGenerationOptions.MixinData.GetMixinInstance(interfaceType);
- string message = string.Format(
- "The mixin {0} adds the
interface '{1}' to the generated proxy, but the interface already exists in the
proxy's {2}. " +
- "A mixin cannot add an
interface already implemented in another way.",
-
mixinWithSameInterface.GetType().Name,
- interfaceType.FullName,
- roleOfCheckedInterface);
- throw new
InvalidMixinConfigurationException(message);
- }
-
- // since interfaces have to form an inheritance graph
without cycles, this recursion should be safe
- ValidateMixinInterfaces(interfaceType.GetInterfaces(),
roleOfCheckedInterface);
- }
-
protected void AddMapping(Type @interface, ITypeContributor
implementer, IDictionary<Type, ITypeContributor> mapping)
{
File [added]: MinimialisticMethodGenerator.cs
Delta lines: None
None
Directory: /DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/
==================================================================
File [modified]: BaseProxyGenerator.cs
Delta lines: +10 -13
===================================================================
--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/EventToGenerate.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/EventToGenerate.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -78,26 +78,23 @@
/// <param name="attributes">The attributes.</param>
public EventToGenerate(string name, Type type, MethodToGenerate
adder, MethodToGenerate remover, EventAttributes attributes)
{
- this.name = GetName(name, adder, remover);
+ if (adder == null)
+ {
+ throw new ArgumentNullException("adder");
+ }
+ if (remover == null)
+ {
+ throw new ArgumentNullException("remover");
+ }
+ this.name = GetName(name, adder.Method.DeclaringType);
this.type = type;
this.adder = adder;
this.remover = remover;
this.Attributes = attributes;
}
- private string GetName(string name, IProxyMethod adder,
IProxyMethod remover)
+ private string GetName(string name, Type declaringType)
{
- Type declaringType = null;
- if (adder != null)
- {
- declaringType = adder.Method.DeclaringType;
- }
- else if (remover != null)
- {
- declaringType = remover.Method.DeclaringType;
- }
-
- Debug.Assert(declaringType != null);
if (!declaringType.IsInterface)
{
File [modified]: EventToGenerate.cs
Delta lines: +65 -0
===================================================================
--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/GeneratorUtil.cs
(rev 0)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/GeneratorUtil.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -0,0 +1,65 @@
+// Copyright 2004-2009 Castle Project - http://www.castleproject.org/
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+namespace Castle.DynamicProxy.Generators
+{
+ using System.Reflection;
+
+ using Castle.DynamicProxy.Generators.Emitters;
+ using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
+ using Castle.DynamicProxy.Tokens;
+
+ public static class GeneratorUtil
+ {
+ public static void CopyOutAndRefParameters(TypeReference[]
dereferencedArguments, LocalReference invocation, MethodInfo method,
MethodEmitter emitter)
+ {
+ var parameters = method.GetParameters();
+ if (!ArgumentsUtil.IsAnyByRef(parameters))
+ {
+ return; //saving the need to create locals if
there is no need
+ }
+
+ var arguments =
StoreInvocationArgumentsInLocal(emitter, invocation);
+
+ for (int i = 0; i < parameters.Length; i++)
+ {
+ if (!parameters[i].ParameterType.IsByRef)
continue;
+
+
emitter.CodeBuilder.AddStatement(AssignArgument(dereferencedArguments, i,
arguments));
+ }
+ }
+
+ private static AssignStatement AssignArgument(TypeReference[]
dereferencedArguments, int i, LocalReference invocationArgs)
+ {
+ return new AssignStatement(dereferencedArguments[i],
Argument(i, invocationArgs, dereferencedArguments));
+ }
+
+ private static ConvertExpression Argument(int i, LocalReference
invocationArgs, TypeReference[] arguments)
+ {
+ return new ConvertExpression(arguments[i].Type, new
LoadRefArrayElementExpression(i, invocationArgs));
+ }
+
+ private static LocalReference
StoreInvocationArgumentsInLocal(MethodEmitter emitter, LocalReference
invocation)
+ {
+ var invocationArgs =
emitter.CodeBuilder.DeclareLocal(typeof(object[]));
+
emitter.CodeBuilder.AddStatement(GetArguments(invocationArgs, invocation));
+ return invocationArgs;
+ }
+
+ private static AssignStatement GetArguments(LocalReference
invocationArgs, LocalReference invocation)
+ {
+ return new AssignStatement(invocationArgs, new
MethodInvocationExpression(invocation, InvocationMethods.GetArguments));
+ }
+ }
+}
File [added]: GeneratorUtil.cs
Delta lines: +0 -2
===================================================================
--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/IProxyMethod.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/IProxyMethod.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -20,8 +20,6 @@
{
MethodInfo Method { get; }
- // TODO: this should be removed, outsourced to the target
itself, since target is neved null anyway
bool HasTarget { get; }
- MethodInfo MethodOnTarget { get; }
}
}
File [modified]: IProxyMethod.cs
Delta lines: +73 -166
===================================================================
---
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceMethodGenerator.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/InterfaceMethodGenerator.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -27,200 +27,117 @@
using Castle.DynamicProxy.Generators.Emitters.SimpleAST;
using Castle.DynamicProxy.Tokens;
- public class InterfaceMethodGenerator : MethodGenerator
+ public class InterfaceMethodGenerator : InterfaceMethodGeneratorBase
{
private readonly NestedClassEmitter invocation;
private readonly FieldReference interceptors;
- private readonly CreateMethodDelegate createMethod;
private readonly GetTargetExpressionDelegate
getTargetExpression;
- private readonly MethodToGenerate method;
public InterfaceMethodGenerator(MethodToGenerate method,
NestedClassEmitter invocation, FieldReference interceptors,
CreateMethodDelegate createMethod,GetTargetExpressionDelegate
getTargetExpression)
+ :base(method,createMethod)
{
- Debug.Assert(method.Method.DeclaringType.IsInterface,
"method.Method.DeclaringType.IsInterface");
- this.method = method;
+ Debug.Assert(method.MethodOnTarget != null,
"method.MethodOnTarget != null");
this.invocation = invocation;
this.interceptors = interceptors;
- this.createMethod = createMethod;
this.getTargetExpression = getTargetExpression;
}
- public override MethodEmitter Generate(ClassEmitter @class,
ProxyGenerationOptions options, INamingScope namingScope)
+ protected override MethodEmitter
ImplementProxiedMethod(MethodEmitter emitter, ClassEmitter @class,
ProxyGenerationOptions options,INamingScope namingScope)
{
- string name;
- MethodAttributes atts = ObtainMethodAttributes(out
name);
- MethodEmitter methodEmitter = createMethod(name, atts);
- MethodEmitter proxiedMethod =
ImplementProxiedMethod(methodEmitter,
-
@class,
-
options, namingScope);
+ emitter.CopyParametersAndReturnTypeFrom(Method.Method,
@class);
-
@class.TypeBuilder.DefineMethodOverride(methodEmitter.MethodBuilder,
method.Method);
- return proxiedMethod;
- }
-
- private MethodAttributes ObtainMethodAttributes(out string name)
- {
- var methodInfo = method.Method;
- name = methodInfo.DeclaringType.Name + "." +
methodInfo.Name;
- var attributes = MethodAttributes.Virtual |
- MethodAttributes.Private |
- MethodAttributes.HideBySig |
- MethodAttributes.NewSlot |
- MethodAttributes.Final;
-
- if (method.Standalone == false)
- {
- attributes |= MethodAttributes.SpecialName;
- }
- return attributes;
- }
-
- private MethodEmitter ImplementProxiedMethod(MethodEmitter
emitter, ClassEmitter @class, ProxyGenerationOptions options,INamingScope
namingScope)
- {
- emitter.CopyParametersAndReturnTypeFrom(method.Method,
@class);
-
- TypeReference[] dereferencedArguments =
IndirectReference.WrapIfByRef(emitter.Arguments);
-
Type invocationType = invocation.TypeBuilder;
- Trace.Assert(method.Method.IsGenericMethod ==
invocationType.IsGenericTypeDefinition);
+ //TODO: can this ever happen? Should we throw instead?
+ Trace.Assert(Method.Method.IsGenericMethod ==
invocationType.IsGenericTypeDefinition);
-
Expression interfaceMethod;
Expression targetMethod;
- bool isGenericInvocationClass = false;
+
+ ConstructorInfo constructor =
invocation.Constructors[0].ConstructorBuilder;
Type[] genericMethodArgs = Type.EmptyTypes;
- string tokenFieldName;
- Expression targetType;
+ string tokenFieldName =
namingScope.GetUniqueName("token_" + Method.Method.Name);
- // TODO: clean up all these if / else
- if(method.MethodOnTarget!=null)
+ Expression targetType = new
TypeTokenExpression(Method.MethodOnTarget.DeclaringType);
+ if (Method.Method.IsGenericMethod)
{
- targetType = new
TypeTokenExpression(method.MethodOnTarget.DeclaringType);
- }
- else
- {
- targetType = new
TypeTokenExpression(method.Method.DeclaringType);
- }
- if (method.Method.IsGenericMethod)
- {
// bind generic method arguments to
invocation's type arguments
genericMethodArgs =
emitter.MethodBuilder.GetGenericArguments();
invocationType =
invocationType.MakeGenericType(genericMethodArgs);
- isGenericInvocationClass = true;
+ constructor =
TypeBuilder.GetConstructor(invocationType, constructor);
+
// Not in the cache: generic method
- MethodInfo genericMethod =
method.Method.MakeGenericMethod(genericMethodArgs);
+ interfaceMethod = new
MethodTokenExpression(Method.Method.MakeGenericMethod(genericMethodArgs));
+ targetMethod = new
MethodTokenExpression(Method.MethodOnTarget.MakeGenericMethod(genericMethodArgs));
-
- tokenFieldName =
namingScope.GetUniqueName("token_" + method.Method.Name);
- interfaceMethod = new
MethodTokenExpression(genericMethod);
- if (method.MethodOnTarget != null)
- {
- targetMethod = new
MethodTokenExpression(method.MethodOnTarget.MakeGenericMethod(genericMethodArgs));
- }
- else
- {
- targetMethod = NullExpression.Instance;
- }
}
else
{
- var cctor = @class.ClassConstructor;
- var interfaceMethodToken =
@class.CreateStaticField(namingScope.GetUniqueName("token_" +
method.Method.Name),
-
typeof(MethodInfo));
+ var proxiedMethodToken =
@class.CreateStaticField(tokenFieldName, typeof(MethodInfo));
+ var targetMethodToken =
@class.CreateStaticField(namingScope.GetUniqueName("token_" +
Method.MethodOnTarget.Name),
+
typeof(MethodInfo));
+ interfaceMethod =
proxiedMethodToken.ToExpression();
+ targetMethod = targetMethodToken.ToExpression();
- tokenFieldName =
interfaceMethodToken.Reference.Name;
- interfaceMethod =
interfaceMethodToken.ToExpression();
- cctor.CodeBuilder.AddStatement(new
AssignStatement(interfaceMethodToken, new
MethodTokenExpression(method.Method)));
- if (method.MethodOnTarget != null)
- {
- var targetMethodToken =
@class.CreateStaticField(namingScope.GetUniqueName("token_" +
method.MethodOnTarget.Name),
-
typeof(MethodInfo));
- targetMethod =
targetMethodToken.ToExpression();
- cctor.CodeBuilder.AddStatement(
- new
AssignStatement(targetMethodToken, new
MethodTokenExpression(method.MethodOnTarget)));
- }
- else
- {
- targetMethod = NullExpression.Instance;
- }
+ var cctor = @class.ClassConstructor;
+ cctor.CodeBuilder.AddStatement(new
AssignStatement(proxiedMethodToken, new MethodTokenExpression(Method.Method)));
+ cctor.CodeBuilder.AddStatement(new
AssignStatement(targetMethodToken,
+
new MethodTokenExpression(Method.MethodOnTarget)));
}
- LocalReference invocationImplLocal =
emitter.CodeBuilder.DeclareLocal(invocationType);
- // TODO: Initialize iinvocation instance with ordinary
arguments and in and out arguments
+ var dereferencedArguments =
IndirectReference.WrapIfByRef(emitter.Arguments);
- ConstructorInfo constructor =
invocation.Constructors[0].ConstructorBuilder;
- if (isGenericInvocationClass)
- {
- constructor =
TypeBuilder.GetConstructor(invocationType, constructor);
- }
-
-
- Expression target = getTargetExpression(@class,
method.Method);
-
- NewInstanceExpression newInvocImpl;
+ Expression[] ctorArguments;
if (options.Selector == null)
{
- newInvocImpl = //actual contructor call
- new NewInstanceExpression(constructor,
- target,
-
SelfReference.Self.ToExpression(),
-
interceptors.ToExpression(),
- // NOTE:
there's no need to cache type token
- // profiling
showed that it gives no real performance gain
- targetType,
- targetMethod,
-
interfaceMethod,
- new
ReferencesToObjectArrayExpression(dereferencedArguments));
+ ctorArguments = new[]
+ {
+ getTargetExpression(@class,
Method.Method),
+ SelfReference.Self.ToExpression(),
+ interceptors.ToExpression(),
+ targetType,
+ targetMethod,
+ interfaceMethod,
+ new
ReferencesToObjectArrayExpression(dereferencedArguments)
+ };
}
else
{
- // Create the field to store the selected
interceptors for this method if an InterceptorSelector is specified
- // NOTE: If no interceptors are returned,
should we invoke the base.Method directly? Looks like we should not.
- FieldReference methodInterceptors =
@class.CreateField(string.Format("{0}_interceptors", tokenFieldName),
-
typeof(IInterceptor[]), false);
-#if !SILVERLIGHT
-
@class.DefineCustomAttributeFor<XmlIgnoreAttribute>(methodInterceptors);
-#endif
-
- var selector = new MethodInvocationExpression(
-
@class.GetField("proxyGenerationOptions"),
-
ProxyGenerationOptionsMethods.GetSelector) { VirtualCall = true };
-
- newInvocImpl = //actual contructor call
- new NewInstanceExpression(constructor,
- target,
-
SelfReference.Self.ToExpression(),
-
interceptors.ToExpression(),
- targetType,
- targetMethod,
-
interfaceMethod,
- new
ReferencesToObjectArrayExpression(dereferencedArguments),
- selector,
- new
AddressOfReferenceExpression(methodInterceptors));
+ ctorArguments = new[]
+ {
+ getTargetExpression(@class,
Method.Method),
+ SelfReference.Self.ToExpression(),
+ interceptors.ToExpression(),
+ targetType,
+ targetMethod,
+ interfaceMethod,
+ new
ReferencesToObjectArrayExpression(dereferencedArguments),
+ BuildGetSelectorInvocation(@class),
+ new
AddressOfReferenceExpression(BuildMethodInterceptorsFiled(@class,
tokenFieldName))
+ };
}
- emitter.CodeBuilder.AddStatement(new
AssignStatement(invocationImplLocal, newInvocImpl));
+ var invocationLocal =
emitter.CodeBuilder.DeclareLocal(invocationType);
+ emitter.CodeBuilder.AddStatement(new
AssignStatement(invocationLocal,
+
new NewInstanceExpression(constructor, ctorArguments)));
- if (method.Method.ContainsGenericParameters)
+ if (Method.Method.ContainsGenericParameters)
{
- EmitLoadGenricMethodArguments(emitter,
method.Method.MakeGenericMethod(genericMethodArgs), invocationImplLocal);
+ EmitLoadGenricMethodArguments(emitter,
Method.Method.MakeGenericMethod(genericMethodArgs), invocationLocal);
}
emitter.CodeBuilder.AddStatement(
- new ExpressionStatement(new
MethodInvocationExpression(invocationImplLocal, InvocationMethods.Proceed)));
+ new ExpressionStatement(new
MethodInvocationExpression(invocationLocal, InvocationMethods.Proceed)));
- CopyOutAndRefParameters(dereferencedArguments,
invocationImplLocal, method.Method, emitter);
+
GeneratorUtil.CopyOutAndRefParameters(dereferencedArguments, invocationLocal,
Method.Method, emitter);
- if (method.Method.ReturnType != typeof(void))
+ if (Method.Method.ReturnType != typeof(void))
{
// Emit code to return with cast from
ReturnValue
- var getRetVal = new
MethodInvocationExpression(invocationImplLocal,
InvocationMethods.GetReturnValue);
-
- emitter.CodeBuilder.AddStatement(
- new ReturnStatement(new
ConvertExpression(emitter.ReturnType, getRetVal)));
+ var getRetVal = new
MethodInvocationExpression(invocationLocal, InvocationMethods.GetReturnValue);
+ emitter.CodeBuilder.AddStatement(new
ReturnStatement(new ConvertExpression(emitter.ReturnType, getRetVal)));
}
else
{
@@ -230,33 +147,23 @@
return emitter;
}
- private static void CopyOutAndRefParameters(TypeReference[]
dereferencedArguments, LocalReference invocationImplLocal, MethodInfo method,
MethodEmitter methodEmitter)
+ private MethodInvocationExpression
BuildGetSelectorInvocation(ClassEmitter @class)
{
- var parameters = method.GetParameters();
- if(!ArgumentsUtil.IsAnyByRef(parameters))
- {
- return; //saving the need to create locals if
there is no need
- }
- LocalReference invocationArgs =
methodEmitter.CodeBuilder.DeclareLocal(typeof(object[]));
- methodEmitter.CodeBuilder.AddStatement(
- new AssignStatement(invocationArgs,
- new
MethodInvocationExpression(invocationImplLocal, InvocationMethods.GetArguments)
- )
- );
- for (int i = 0; i < parameters.Length; i++)
- {
- if (parameters[i].ParameterType.IsByRef)
- {
- methodEmitter.CodeBuilder.AddStatement(
- new
AssignStatement(dereferencedArguments[i],
- new
ConvertExpression(dereferencedArguments[i].Type,
-
new LoadRefArrayElementExpression(i, invocationArgs)
- )
- ));
- }
- }
+ return new MethodInvocationExpression(
+ @class.GetField("proxyGenerationOptions"),
+ ProxyGenerationOptionsMethods.GetSelector) {
VirtualCall = true };
}
+ private FieldReference
BuildMethodInterceptorsFiled(ClassEmitter @class, string tokenFieldName)
+ {
+ FieldReference methodInterceptors =
@class.CreateField(string.Format("{0}_interceptors", tokenFieldName),
+
typeof(IInterceptor[]), false);
+#if !SILVERLIGHT
+
@class.DefineCustomAttributeFor<XmlIgnoreAttribute>(methodInterceptors);
+#endif
+ return methodInterceptors;
+ }
+
private void EmitLoadGenricMethodArguments(MethodEmitter
methodEmitter, MethodInfo method,
LocalReference
invocationImplLocal)
File [modified]: InterfaceMethodGenerator.cs
Delta lines: +20 -3
===================================================================
--- DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/MethodToGenerate.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++ DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/MethodToGenerate.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -17,15 +17,18 @@
using System.Reflection;
using Contributors;
- public class MethodToGenerate : ProxyMethod
+ public class MethodToGenerate : IProxyMethod
{
private readonly bool standalone;
private readonly MethodInfo methodOnTarget;
private readonly bool proxyable;
+ private readonly MethodInfo method;
+ private readonly ITypeContributor target;
public MethodToGenerate(MethodInfo method, bool standalone,
ITypeContributor target, MethodInfo methodOnTarget, bool proxyable)
- : base(method,target)
{
+ this.method = method;
+ this.target = target;
this.standalone = standalone;
this.methodOnTarget = methodOnTarget;
this.proxyable = proxyable;
@@ -36,7 +39,7 @@
get { return proxyable; }
}
- public override MethodInfo MethodOnTarget
+ public MethodInfo MethodOnTarget
{
get { return methodOnTarget; }
}
@@ -45,5 +48,19 @@
{
get { return standalone; }
}
+
+ public MethodInfo Method
+ {
+ get { return method; }
+ }
+
+ public bool HasTarget
+ {
+ get
+ {
+ return target != null;
+ }
+ }
+
}
}
File [modified]: MethodToGenerate.cs
Delta lines: +1 -28
===================================================================
---
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/MethodWithCallbackGenerator.cs
2009-11-10 17:59:08 UTC (rev 6310)
+++
DynamicProxy/trunk/src/Castle.DynamicProxy/Generators/MethodWithCallbackGenerator.cs
2009-11-10 21:08:21 UTC (rev 6311)
@@ -172,7 +172,7 @@
emitter.CodeBuilder.AddStatement(
new ExpressionStatement(new
MethodInvocationExpression(invocationImplLocal, InvocationMethods.Proceed)));
- CopyOutAndRefParameters(dereferencedArguments,
invocationImplLocal, methodInfo, emitter);
+
GeneratorUtil.CopyOutAndRefParameters(dereferencedArguments,
invocationImplLocal, methodInfo, emitter);
if (methodInfo.ReturnType != typeof(void))
{
@@ -191,33 +191,6 @@
return emitter;
}
- private static void CopyOutAndRefParameters(TypeReference[]
dereferencedArguments, Reference invocationImplLocal, MethodInfo method,
MethodEmitter methodEmitter)
- {
- var parameters = method.GetParameters();
- if (!ArgumentsUtil.IsAnyByRef(parameters))
- return; //saving the need to create locals if
there is no need
- LocalReference invocationArgs =
methodEmitter.CodeBuilder.DeclareLocal(typeof(object[]));
- methodEmitter.CodeBuilder.AddStatement(
- new AssignStatement(invocationArgs,
- new
MethodInvocationExpression(invocationImplLocal, InvocationMethods.GetArguments)
- )
- );
- for (int i = 0; i < parameters.Length; i++)
- {
- if (parameters[i].ParameterType.IsByRef)
- {
- methodEmitter.CodeBuilder.AddStatement(
- new
AssignStatement(dereferencedArguments[i],
- new
ConvertExpression(dereferencedArguments[i].Type,
-
new LoadRefArrayElementExpression(i, invocationArgs)
- )
- ));
- }
- }
- }
-
-
-
private void EmitLoadGenricMethodArguments(MethodEmitter
methodEmitter, MethodInfo method, Reference invocationImplLocal)
{
File [modified]: MethodWithCallbackGenerator.cs
Delta lines: +0 -0
===================================================================
--
You received this message because you are subscribed to the Google Groups
"Castle Project Commits" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/castle-project-commits?hl=.