private void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor, params FieldReference[] fields) { ArgumentReference[] args; ParameterInfo[] baseConstructorParams = null; if (baseConstructor != null) { baseConstructorParams = baseConstructor.GetParameters(); } if (baseConstructorParams != null && baseConstructorParams.Length != 0) { args = new ArgumentReference[fields.Length + baseConstructorParams.Length]; int offset = fields.Length; for (int i = offset; i < offset + baseConstructorParams.Length; i++) { ParameterInfo paramInfo = baseConstructorParams[i - offset]; args[i] = new ArgumentReference(paramInfo.ParameterType); } } else { args = new ArgumentReference[fields.Length]; } for (int i = 0; i < fields.Length; i++) { args[i] = new ArgumentReference(fields[i].Reference.FieldType); } ConstructorEmitter constructor = emitter.CreateConstructor(args); for (int i = 0; i < fields.Length; i++) { constructor.CodeBuilder.AddStatement(new AssignStatement(fields[i], args[i].ToExpression())); } // Invoke base constructor if (baseConstructor != null) { Debug.Assert(baseConstructorParams != null); var slice = new ArgumentReference[baseConstructorParams.Length]; Array.Copy(args, fields.Length, slice, 0, baseConstructorParams.Length); constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, slice); } else { constructor.CodeBuilder.InvokeBaseConstructor(); } constructor.CodeBuilder.AddStatement(new ReturnStatement()); }
/// <summary> /// Generates a parameters constructor that initializes the proxy /// state with <see cref="StandardInterceptor"/> just to make it non-null. /// <para> /// This constructor is important to allow proxies to be XML serializable /// </para> /// </summary> protected void GenerateParameterlessConstructor(ClassEmitter emitter, Type baseClass, FieldReference interceptorField) { // Check if the type actually has a default constructor ConstructorInfo defaultConstructor = baseClass.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null); if (defaultConstructor == null) { defaultConstructor = baseClass.GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, Type.EmptyTypes, null); if (defaultConstructor == null || defaultConstructor.IsPrivate) { return; } } ConstructorEmitter constructor = emitter.CreateConstructor(); // initialize fields with an empty interceptor constructor.CodeBuilder.AddStatement(new AssignStatement(interceptorField, new NewArrayExpression(1, typeof (IInterceptor)))); constructor.CodeBuilder.AddStatement( new AssignArrayStatement(interceptorField, 0, new NewInstanceExpression(typeof(StandardInterceptor), new Type[0]))); // Invoke base constructor constructor.CodeBuilder.InvokeBaseConstructor(defaultConstructor); constructor.CodeBuilder.AddStatement(new ReturnStatement()); }
public void NoCustomCtorForInterfaces() { DisableVerification(); ClassEmitter emitter = new ClassEmitter(generator.ProxyBuilder.ModuleScope, "IFoo", null, Type.EmptyTypes, TypeAttributes.Interface | TypeAttributes.Abstract | TypeAttributes.Public, false); emitter.CreateConstructor(); }
protected void GenerateConstructor(ClassEmitter emitter, ConstructorInfo baseConstructor, params FieldReference[] fields) { ArgumentReference[] args; ParameterInfo[] baseConstructorParams = null; if (baseConstructor != null) { baseConstructorParams = baseConstructor.GetParameters(); } if (baseConstructorParams != null && baseConstructorParams.Length != 0) { args = new ArgumentReference[fields.Length + baseConstructorParams.Length]; var offset = fields.Length; for (var i = offset; i < offset + baseConstructorParams.Length; i++) { var paramInfo = baseConstructorParams[i - offset]; args[i] = new ArgumentReference(paramInfo.ParameterType); } } else { args = new ArgumentReference[fields.Length]; } for (var i = 0; i < fields.Length; i++) { args[i] = new ArgumentReference(fields[i].Reference.FieldType); } var constructor = emitter.CreateConstructor(args); if (baseConstructorParams != null && baseConstructorParams.Length != 0) { var last = baseConstructorParams.Last(); #if !NETFX_CORE if (last.ParameterType.IsArray && last.HasAttribute<ParamArrayAttribute>()) #else if (last.ParameterType.IsArray && ParameterInfoExtender.HasAttribute<ParamArrayAttribute>(last)) #endif { var parameter = constructor.ConstructorBuilder.DefineParameter(args.Length, ParameterAttributes.None, last.Name); var builder = AttributeUtil.CreateBuilder<ParamArrayAttribute>(); parameter.SetCustomAttribute(builder); } } for (var i = 0; i < fields.Length; i++) { constructor.CodeBuilder.AddStatement(new AssignStatement(fields[i], args[i].ToExpression())); } // Invoke base constructor if (baseConstructor != null) { Debug.Assert(baseConstructorParams != null); var slice = new ArgumentReference[baseConstructorParams.Length]; Array.Copy(args, fields.Length, slice, 0, baseConstructorParams.Length); constructor.CodeBuilder.InvokeBaseConstructor(baseConstructor, slice); } else { constructor.CodeBuilder.InvokeBaseConstructor(); } constructor.CodeBuilder.AddStatement(new ReturnStatement()); }
private void GenerateSerializationConstructor(ClassEmitter emitter) { var serializationInfo = new ArgumentReference(typeof(SerializationInfo)); var streamingContext = new ArgumentReference(typeof(StreamingContext)); var ctor = emitter.CreateConstructor(serializationInfo, streamingContext); ctor.CodeBuilder.AddStatement( new ConstructorInvocationStatement(serializationConstructor, serializationInfo.ToExpression(), streamingContext.ToExpression())); foreach (var field in serializedFields) { var getValue = new MethodInvocationExpression(serializationInfo, SerializationInfoMethods.GetValue, new ConstReference(field.Reference.Name).ToExpression(), new TypeTokenExpression(field.Reference.FieldType)); ctor.CodeBuilder.AddStatement(new AssignStatement( field, new ConvertExpression(field.Reference.FieldType, typeof(object), getValue))); } ctor.CodeBuilder.AddStatement(new ReturnStatement()); }
/// <summary> /// Builds the adapter. /// </summary> /// <returns></returns> public Type Build() { //Setup emitter ClassEmitter classEmitter = new ClassEmitter(ModuleScope, OriginalObject.Name + "Adapter", typeof(AdapterBase), new Type[] { }, TypeAttributes.Class, true); //Add a field to hold a reference to the original object that is being adapter. FieldReference adaptedObjectReference = classEmitter.CreateField("_Original", OriginalObject); //Add a constructor that accepts a reference to the original object and //assigns that reference to the field. ArgumentReference parameter = new ArgumentReference(OriginalObject); ConstructorEmitter constructor = classEmitter.CreateConstructor(parameter); constructor.CodeBuilder.AddStatement( new AssignStatement(adaptedObjectReference, new ReferenceExpression(parameter))); constructor.CodeBuilder.AddStatement(new ReturnStatement()); //For each method, walk the pipeline foreach (MethodInfo method in OriginalObject.GetMethods()) { AdapterBuilderStageContext context = new AdapterBuilderStageContext(OriginalObject, classEmitter, adaptedObjectReference, method); WalkPipeline(context); } //build the type return classEmitter.BuildType(); }
protected void GenerateSerializationConstructor(ClassEmitter emitter, FieldReference interceptorField, bool delegateToBaseGetObjectData) { ArgumentReference arg1 = new ArgumentReference(typeof(SerializationInfo)); ArgumentReference arg2 = new ArgumentReference(typeof(StreamingContext)); ConstructorEmitter constr = emitter.CreateConstructor(arg1, arg2); constr.CodeBuilder.AddStatement( new ConstructorInvocationStatement(serializationConstructor, arg1.ToExpression(), arg2.ToExpression())); Type[] object_arg = new Type[] {typeof(String), typeof(Type)}; MethodInfo getValueMethod = typeof(SerializationInfo).GetMethod("GetValue", object_arg); MethodInvocationExpression getInterceptorInvocation = new MethodInvocationExpression(arg1, getValueMethod, new ConstReference("__interceptors").ToExpression(), new TypeTokenExpression(typeof(IInterceptor[]))); constr.CodeBuilder.AddStatement(new AssignStatement( interceptorField, new ConvertExpression(typeof(IInterceptor[]), typeof(object), getInterceptorInvocation))); constr.CodeBuilder.AddStatement(new ReturnStatement()); }