private Delegate EmitMethodEpilogue <T>(ExpressionTreeContext context, Type delegateType, T method, ExpressionConstruct construct)
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("----{0}----", method);
                construct.ToString(SerializerDebugging.ILTraceWriter);
                SerializerDebugging.FlushTraceData();
            }

            var lambda =
                Expression.Lambda(
                    delegateType,
                    construct.Expression,
                    method.ToString(),
                    false,
                    context.GetCurrentParameters()
                    );

#if !NETFX_CORE && !SILVERLIGHT
            if (SerializerDebugging.DumpEnabled)
            {
                var mb =
                    this._typeBuilder.DefineMethod(
                        method.ToString(),
                        MethodAttributes.Public | MethodAttributes.Static,
                        lambda.Type,
                        lambda.Parameters.Select(e => e.Type).ToArray()
                        );
                lambda.CompileToMethod(mb);
            }
#endif
            return(lambda.Compile());
        }
예제 #2
0
        private MethodDefinition EndMethod(ILConstruct body)
        {
            ILMethodConctext lastMethod;

            try
            {
                if (body != null)
                {
                    body.Evaluate(this.IL);
                }

                if (body == null || !body.IsTerminating)
                {
                    this.IL.EmitRet();
                }
            }
            finally
            {
                this.IL.FlushTrace();
#if DEBUG
                SerializerDebugging.FlushTraceData();
#endif // DEBUG
                lastMethod = this._ilGeneratorStack.Pop();
            }

            return(new MethodDefinition(lastMethod.Method, null, lastMethod.ParameterTypes));
        }
예제 #3
0
        /// <summary>
        ///		Gets the IL generator to implement <see cref="MessagePackSerializer{T}.UnpackToCore"/> overrides.
        /// </summary>
        /// <returns>
        ///		The IL generator to implement <see cref="MessagePackSerializer{T}.UnpackToCore"/> overrides.
        /// </returns>
        public override TracingILGenerator GetUnpackToMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}->{1}::{2}", MethodBase.GetCurrentMethod(), this._typeBuilder.Name, this._unpackToMethodBuilder);
            }

            if (this._unpackToMethodBuilder == null)
            {
                this._unpackToMethodBuilder =
                    this._typeBuilder.DefineMethod(
                        "UnpackToCore",
                        MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.Final,
                        CallingConventions.HasThis,
                        null,
                        new[] { typeof(Unpacker), this._unpackFromMethodBuilder.ReturnType }
                        );

#if DEBUG
                Contract.Assert(this._typeBuilder.BaseType != null, "this._typeBuilder.BaseType != null");
#endif
                this._typeBuilder.DefineMethodOverride(this._unpackToMethodBuilder, this._typeBuilder.BaseType.GetMethod(this._unpackToMethodBuilder.Name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
            }

            return(new TracingILGenerator(this._unpackToMethodBuilder, SerializerDebugging.ILTraceWriter, this._isDebuggable));
        }
예제 #4
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="host">The host <see cref="ModuleBuilder"/>.</param>
        /// <param name="specification">The specification of the serializer.</param>
        /// <param name="baseClass">Type of the base class of the serializer.</param>
        /// <param name="isDebuggable">Set to <c>true</c> when <paramref name="host"/> is debuggable.</param>
        public FieldBasedSerializerEmitter(ModuleBuilder host, SerializerSpecification specification, Type baseClass, bool isDebuggable)
        {
            Contract.Requires(host != null);
            Contract.Requires(specification != null);
            Contract.Requires(baseClass != null);

            Tracer.Emit.TraceEvent(Tracer.EventType.DefineType, Tracer.EventId.DefineType, "Create {0}", specification.SerializerTypeFullName);
            this._typeBuilder =
                host.DefineType(
                    specification.SerializerTypeFullName,
                    TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.UnicodeClass | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                    baseClass
                    );

            this._defaultConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
            this._contextConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ConstructorParameterTypes);

            this._traits = specification.TargetCollectionTraits;
            var baseType = this._typeBuilder.BaseType;

#if DEBUG
            Contract.Assert(baseType != null, "baseType != null");
#endif
            this._serializers       = new Dictionary <SerializerFieldKey, SerializerFieldInfo>();
            this._cachedFieldInfos  = new Dictionary <RuntimeFieldHandle, CachedFieldInfo>();
            this._cachedMethodBases = new Dictionary <RuntimeMethodHandle, CachedMethodBase>();
            this._isDebuggable      = isDebuggable;

#if !SILVERLIGHT && !NETFX_35
            if (isDebuggable && SerializerDebugging.DumpEnabled)
            {
                SerializerDebugging.PrepareDump(host.Assembly as AssemblyBuilder);
            }
#endif
        }
예제 #5
0
        /// <summary>
        ///		Gets the IL generator to implement <see cref="MessagePackSerializer{T}.UnpackToCore"/> overrides.
        /// </summary>
        /// <returns>
        ///		The IL generator to implement <see cref="MessagePackSerializer{T}.UnpackToCore"/> overrides.
        /// </returns>
        public override TracingILGenerator GetUnpackToMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}->{1}::{2}", MethodBase.GetCurrentMethod(), this._typeBuilder.Name, "UnpackToCore");
            }

            if (this._unpackToMethodBuilder == null)
            {
#if DEBUG
                Contract.Assert(this._typeBuilder.BaseType != null, "this._typeBuilder.BaseType != null");
#endif // DEBUG
                var baseMethod =
                    this._typeBuilder.BaseType.GetMethod(
                        "UnpackToCore",
                        BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
                        );
                this._unpackToMethodBuilder =
                    this._typeBuilder.DefineMethod(
                        baseMethod.Name,
                        (baseMethod.Attributes | MethodAttributes.Final) & (~MethodAttributes.Abstract),
                        baseMethod.CallingConvention,
                        baseMethod.ReturnType,
                        baseMethod.GetParameters().Select(p => p.ParameterType).ToArray()
                        );
                this._typeBuilder.DefineMethodOverride(
                    this._unpackToMethodBuilder,
                    baseMethod
                    );
            }

            return(new TracingILGenerator(this._unpackToMethodBuilder, SerializerDebugging.ILTraceWriter, this._isDebuggable));
        }
예제 #6
0
        /// <summary>
        ///		Gets the IL generator to implement AddItem(TCollection, TItem) or AddItem(TCollection, object) overrides.
        /// </summary>
        /// <param name="declaration">The virtual method declaration to be overriden.</param>
        /// <returns>
        ///		The IL generator to implement AddItem(TCollection, TItem) or AddItem(TCollection, object) overrides.
        ///		This value will not be <c>null</c>.
        /// </returns>
        public override TracingILGenerator GetAddItemMethodILGenerator(MethodInfo declaration)
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}::{1}", MethodBase.GetCurrentMethod(), "AddItem");
            }

            if (this._addItemMethod == null)
            {
                this._addItemMethod =
                    new DynamicMethod(
                        "AddItem",
                        null,
                        (this._traits.DetailedCollectionType == CollectionDetailedKind.GenericDictionary
#if !NETFX_40 && !NETFX_35 && !SILVERLIGHT
                         || this._traits.DetailedCollectionType == CollectionDetailedKind.GenericReadOnlyDictionary
#endif // !NETFX_40 && !NETFX_35 && !SILVERLIGHT
                        )
                                                ? new[] { typeof(SerializationContext), this._targetType, this._traits.ElementType.GetGenericArguments()[0], this._traits.ElementType.GetGenericArguments()[1] }
                                                : new[] { typeof(SerializationContext), this._targetType, this._traits.ElementType }
                        );
            }

            return(new TracingILGenerator(this._addItemMethod, SerializerDebugging.ILTraceWriter));
        }
        public override TracingILGenerator GetUnpackFromUnderlyingValueMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}::{1}", MethodBase.GetCurrentMethod(), this._unpackFromUnderlyingValueMethod);
            }

            return(new TracingILGenerator(this._unpackFromUnderlyingValueMethod, SerializerDebugging.ILTraceWriter));
        }
예제 #8
0
        public override TracingILGenerator GetUnpackFromUnderlyingValueMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}->{1}::{2}", MethodBase.GetCurrentMethod(), this._typeBuilder.Name, this._unpackFromUnderlyingValueMethodBuilder);
            }

            return(new TracingILGenerator(this._unpackFromUnderlyingValueMethodBuilder, SerializerDebugging.ILTraceWriter, this._isDebuggable));
        }
예제 #9
0
        /// <summary>
        ///		Initializes a new instance of the <see cref="ExpressionTreeSerializerBuilder{TObject}"/> class.
        /// </summary>
        public ExpressionTreeSerializerBuilder()
        {
#if !NETFX_CORE && !SILVERLIGHT
            if (SerializerDebugging.DumpEnabled)
            {
                SerializerDebugging.PrepareDump();
                this._typeBuilder = SerializerDebugging.NewTypeBuilder(typeof(TObject));
            }
#endif
        }
예제 #10
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="host">The host <see cref="ModuleBuilder"/>.</param>
        /// <param name="sequence">The sequence number to name new type.</param>
        /// <param name="targetType">Type of the serialization target.</param>
        /// <param name="baseClass">Type of the base class of the serializer.</param>
        /// <param name="isDebuggable">Set to <c>true</c> when <paramref name="host"/> is debuggable.</param>
        public FieldBasedSerializerEmitter(ModuleBuilder host, int?sequence, Type targetType, Type baseClass, bool isDebuggable)
        {
            Contract.Requires(host != null);
            Contract.Requires(targetType != null);
            Contract.Requires(baseClass != null);

            string typeName =
#if !NETFX_35
                String.Join(
                    Type.Delimiter.ToString(CultureInfo.InvariantCulture),
                    typeof(SerializerEmitter).Namespace,
                    "Generated",
                    IdentifierUtility.EscapeTypeName(targetType) + "Serializer" + sequence
                    );
#else
                String.Join(
                    Type.Delimiter.ToString(),
                    new string[]
            {
                typeof(SerializerEmitter).Namespace,
                "Generated",
                IdentifierUtility.EscapeTypeName(targetType) + "Serializer" + sequence
            }
                    );
#endif
            Tracer.Emit.TraceEvent(Tracer.EventType.DefineType, Tracer.EventId.DefineType, "Create {0}", typeName);
            this._typeBuilder =
                host.DefineType(
                    typeName,
                    TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.UnicodeClass | TypeAttributes.AutoLayout | TypeAttributes.BeforeFieldInit,
                    baseClass
                    );

            this._defaultConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, Type.EmptyTypes);
            this._contextConstructorBuilder = this._typeBuilder.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, ConstructorParameterTypes);

            this._targetType = targetType;
            this._traits     = targetType.GetCollectionTraits();
            var baseType = this._typeBuilder.BaseType;
#if DEBUG
            Contract.Assert(baseType != null, "baseType != null");
#endif
            this._serializers  = new Dictionary <SerializerFieldKey, SerializerFieldInfo>();
            this._fieldInfos   = new Dictionary <RuntimeFieldHandle, FieldBuilder>();
            this._methodBases  = new Dictionary <RuntimeMethodHandle, FieldBuilder>();
            this._isDebuggable = isDebuggable;

#if !SILVERLIGHT && !NETFX_35
            if (isDebuggable && SerializerDebugging.DumpEnabled)
            {
                SerializerDebugging.PrepareDump(host.Assembly as AssemblyBuilder);
            }
#endif
        }
예제 #11
0
        private ConstructorBuilder CreateConstructor(MethodAttributes attributes, Type[] parameterTypes, Action <Type, TracingILGenerator> emitter)
        {
            var builder = this.DefineConstructor(attributes, parameterTypes);

            emitter(this._typeBuilder.BaseType, this.GetILGenerator(builder, parameterTypes));

            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.FlushTraceData();
            }

            return(builder);
        }
        public void DefineUnpackingContext(string name, IList <KeyValuePair <string, Type> > fields, out Type type, out ConstructorInfo constructor)
        {
            this._unpackingContextType =
                this._host.DefineType(
                    this._typeBuilder.FullName + "_" + name,
                    TypeAttributes.Class | TypeAttributes.UnicodeClass | TypeAttributes.NotPublic | TypeAttributes.Sealed | TypeAttributes.BeforeFieldInit
                    );
            var parameterTypes = fields.Select(kv => kv.Value).ToArray();
            var ctor           =
                this._unpackingContextType.DefineConstructor(
                    MethodAttributes.Public,
                    CallingConventions.Standard,
                    parameterTypes
                    );
            var il = this.GetILGenerator(ctor, parameterTypes);

            try
            {
                // call object.ctor
                il.EmitLdargThis();
                il.EmitCallConstructor(Metadata._Object.Ctor);

                for (var i = 0; i < fields.Count; i++)
                {
                    var field = this._unpackingContextType.DefineField(fields[i].Key, fields[i].Value, FieldAttributes.Public);
                    il.EmitLdargThis();
                    il.EmitAnyLdarg(i + 1);
                    il.EmitStfld(field);
                }

                il.EmitRet();
            }
            finally
            {
                il.FlushTrace();
#if DEBUG
                SerializerDebugging.FlushTraceData();
#endif // DEBUG
            }

#if !NETSTANDARD1_1 && !NETSTANDARD1_3 && !NETSTANDARD2_0
            type = this._unpackingContextType.CreateType();
#else
            type = this._unpackingContextType.CreateTypeInfo().AsType();
#endif // !NETSTANDARD1_1 && !NETSTANDARD1_3 && !NETSTANDARD2_0
            constructor = type.GetConstructors().Single();
        }
예제 #13
0
        /// <summary>
        ///		Gets the IL generator to implement <see cref="MessagePackSerializer{T}.UnpackToCore"/> overrides.
        /// </summary>
        /// <returns>
        ///		The IL generator to implement <see cref="MessagePackSerializer{T}.UnpackToCore"/> overrides.
        /// </returns>
        public override TracingILGenerator GetUnpackToMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}::{1}", MethodBase.GetCurrentMethod(), this._unpackToMethod);
            }

            if (this._unpackToMethod == null)
            {
                this._unpackToMethod = new DynamicMethod(
                    "UnpackToCore",
                    null,
                    new[] { typeof(SerializationContext), typeof(Unpacker), this._targetType });
            }

            return(new TracingILGenerator(this._unpackToMethod, SerializerDebugging.ILTraceWriter));
        }
예제 #14
0
        private static void EmitMethodEpilogue(TContext context, ILConstruct construct)
        {
            try
            {
                if (construct != null)
                {
                    construct.Evaluate(context.IL);
                }

                context.IL.EmitRet();
            }
            finally
            {
                context.IL.FlushTrace();
                SerializerDebugging.FlushTraceData();
            }
        }
예제 #15
0
        /// <summary>
        ///		Gets the IL generator to implement <see cref="MessagePackSerializer{T}.UnpackFromCore"/> overrides.
        /// </summary>
        /// <returns>
        ///		The IL generator to implement <see cref="MessagePackSerializer{T}.UnpackFromCore"/> overrides.
        ///		This value will not be <c>null</c>.
        /// </returns>
        public override TracingILGenerator GetUnpackFromMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}::{1}", MethodBase.GetCurrentMethod(), this._unpackFromMethod);
            }

            if (this._unpackFromMethod == null)
            {
                this._unpackFromMethod =
                    new DynamicMethod(
                        "UnpackFromCore",
                        this._targetType,
                        UnpackFromCoreParameterTypes
                        );
            }

            return(new TracingILGenerator(this._unpackFromMethod, SerializerDebugging.ILTraceWriter));
        }
예제 #16
0
        /// <summary>
        ///		Gets the IL generator to implement private static RestoreSchema() method.
        /// </summary>
        /// <returns>
        ///		The IL generator to implement RestoreSchema() static method.
        ///		This value will not be <c>null</c>.
        /// </returns>
        public override TracingILGenerator GetRestoreSchemaMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}::{1}", MethodBase.GetCurrentMethod(), this._restoreSchemaMethod);
            }

            if (this._restoreSchemaMethod == null)
            {
                this._restoreSchemaMethod =
                    new DynamicMethod(
                        "RestoreSchema",
                        typeof(PolymorphismSchema),
                        ReflectionAbstractions.EmptyTypes
                        );
            }

            return(new TracingILGenerator(this._restoreSchemaMethod, SerializerDebugging.ILTraceWriter));
        }
예제 #17
0
        /// <summary>
        ///		Gets the IL generator to implement CreateInstance(int) overrides.
        /// </summary>
        /// <param name="declaration">The virtual method declaration to be overriden.</param>
        /// <returns>
        ///		The IL generator to implement CreateInstance(int) overrides.
        ///		This value will not be <c>null</c>.
        /// </returns>
        public override TracingILGenerator GetCreateInstanceMethodILGenerator(MethodInfo declaration)
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}::{1}", MethodBase.GetCurrentMethod(), this._createInstanceMethod);
            }

            if (this._createInstanceMethod == null)
            {
                this._createInstanceMethod =
                    new DynamicMethod(
                        "CreateInstance",
                        this._targetType,
                        CreateInstanceParameterTypes
                        );
            }

            return(new TracingILGenerator(this._createInstanceMethod, SerializerDebugging.ILTraceWriter));
        }
예제 #18
0
        /// <summary>
        ///		Gets the IL generator to implement AddItem(TCollection, TItem) or AddItem(TCollection, object) overrides.
        /// </summary>
        /// <param name="declaration">The virtual method declaration to be overriden.</param>
        /// <returns>
        ///		The IL generator to implement AddItem(TCollection, TItem) or AddItem(TCollection, object) overrides.
        ///		This value will not be <c>null</c>.
        /// </returns>
        public override TracingILGenerator GetAddItemMethodILGenerator(MethodInfo declaration)
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}::{1}", MethodBase.GetCurrentMethod(), this._addItemMethod);
            }

            if (this._addItemMethod == null)
            {
                this._addItemMethod =
                    new DynamicMethod(
                        "AddItem",
                        null,
                        new[] { typeof(SerializationContext), this._targetType, this._traits.ElementType }
                        );
            }

            return(new TracingILGenerator(this._addItemMethod, SerializerDebugging.ILTraceWriter));
        }
        /// <summary>
        ///		Gets the IL generator to implement private static RestoreSchema() method.
        /// </summary>
        /// <returns>
        ///		The IL generator to implement RestoreSchema() static method.
        ///		This value will not be <c>null</c>.
        /// </returns>
        public override TracingILGenerator GetRestoreSchemaMethodILGenerator()
        {
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.TraceEvent("{0}->{1}::{2}", MethodBase.GetCurrentMethod(), this._typeBuilder.Name, "RestoreSchema");
            }

            if (this._restoreSchemaMethodBuilder == null)
            {
                this._restoreSchemaMethodBuilder =
                    this._typeBuilder.DefineMethod(
                        "RestoreSchema",
                        MethodAttributes.Private | MethodAttributes.Static | MethodAttributes.HideBySig,
                        CallingConventions.Standard,
                        typeof(PolymorphismSchema),
                        ReflectionAbstractions.EmptyTypes
                        );
            }

            return(new TracingILGenerator(this._restoreSchemaMethodBuilder, SerializerDebugging.ILTraceWriter, this._isDebuggable));
        }
예제 #20
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="context">A <see cref="SerializationContext"/>.</param>
        /// <param name="host">The host <see cref="ModuleBuilder"/>.</param>
        /// <param name="specification">The specification of the serializer.</param>
        /// <param name="isDebuggable">Set to <c>true</c> when <paramref name="host"/> is debuggable.</param>
        public FieldBasedEnumSerializerEmitter(SerializationContext context, ModuleBuilder host, SerializerSpecification specification, bool isDebuggable)
        {
            Contract.Requires(host != null);
            Contract.Requires(specification != null);

            Tracer.Emit.TraceEvent(Tracer.EventType.DefineType, Tracer.EventId.DefineType, "Create {0}", specification.SerializerTypeFullName);
            this._typeBuilder =
                host.DefineType(
                    specification.SerializerTypeFullName,
                    TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.UnicodeClass | TypeAttributes.AutoLayout |
                    TypeAttributes.BeforeFieldInit,
                    typeof(EnumMessagePackSerializer <>).MakeGenericType(specification.TargetType)
                    );

            this._contextConstructorBuilder =
                this._typeBuilder.DefineConstructor(
                    MethodAttributes.Public,
                    CallingConventions.Standard,
                    ContextConstructorParameterTypes
                    );
            this._defaultEnumSerializationMethod = context.EnumSerializationMethod;
            this._contextAndEnumSerializationMethodConstructorBuilder =
                this._typeBuilder.DefineConstructor(
                    MethodAttributes.Public,
                    CallingConventions.Standard,
                    ContextAndEnumSerializationMethodConstructorParameterTypes
                    );

            this._packUnderlyingValueToMethodBuilder =
                this._typeBuilder.DefineMethod(
                    "PackUnderlyingValueTo",
                    MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig,
                    CallingConventions.HasThis,
                    typeof(void),
                    new[] { typeof(Packer), specification.TargetType }
                    );

            this._unpackFromUnderlyingValueMethodBuilder =
                this._typeBuilder.DefineMethod(
                    "UnpackFromUnderlyingValue",
                    MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig,
                    CallingConventions.HasThis,
                    specification.TargetType,
                    UnpackFromUnderlyingValueParameterTypes
                    );

            var baseType = this._typeBuilder.BaseType;

#if DEBUG
            Contract.Assert(baseType != null, "baseType != null");
#endif
            this._typeBuilder.DefineMethodOverride(
                this._packUnderlyingValueToMethodBuilder,
                baseType.GetMethod(
                    this._packUnderlyingValueToMethodBuilder.Name,
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
                    )
                );
            this._typeBuilder.DefineMethodOverride(
                this._unpackFromUnderlyingValueMethodBuilder,
                baseType.GetMethod(
                    this._unpackFromUnderlyingValueMethodBuilder.Name,
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
                    )
                );
            this._isDebuggable = isDebuggable;

#if !SILVERLIGHT && !NETFX_35
            if (isDebuggable && SerializerDebugging.DumpEnabled)
            {
                SerializerDebugging.PrepareDump(host.Assembly as AssemblyBuilder);
            }
#endif
        }
예제 #21
0
        /// <summary>
        /// Initializes a new instance of the <see cref="FieldBasedSerializerEmitter"/> class.
        /// </summary>
        /// <param name="host">The host <see cref="ModuleBuilder"/>.</param>
        /// <param name="sequence">The sequence number to name new type.</param>
        /// <param name="targetType">Type of the serialization target.</param>
        /// <param name="isDebuggable">Set to <c>true</c> when <paramref name="host"/> is debuggable.</param>
        public FieldBasedEnumSerializerEmitter(ModuleBuilder host, int?sequence, Type targetType, bool isDebuggable)
        {
            Contract.Requires(host != null);
            Contract.Requires(targetType != null);

            this._constructorParameterTypes =
                new[]
            {
                typeof(SerializationContext),
                typeof(EnumSerializationMethod)
            };

            string typeName =
#if !NETFX_35
                String.Join(
                    Type.Delimiter.ToString(CultureInfo.InvariantCulture),
                    typeof(SerializerEmitter).Namespace,
                    "Generated",
                    IdentifierUtility.EscapeTypeName(targetType) + "Serializer" + sequence
                    );
#else
                String.Join(
                    Type.Delimiter.ToString(),
                    new string[]
            {
                typeof(SerializerEmitter).Namespace,
                "Generated",
                IdentifierUtility.EscapeTypeName(targetType) + "Serializer" + sequence
            }
                    );
#endif
            Tracer.Emit.TraceEvent(Tracer.EventType.DefineType, Tracer.EventId.DefineType, "Create {0}", typeName);
            this._typeBuilder =
                host.DefineType(
                    typeName,
                    TypeAttributes.Sealed | TypeAttributes.Public | TypeAttributes.UnicodeClass | TypeAttributes.AutoLayout |
                    TypeAttributes.BeforeFieldInit,
                    typeof(EnumMessagePackSerializer <>).MakeGenericType(targetType)
                    );

            this._contextConstructorBuilder = this._typeBuilder.DefineConstructor(
                MethodAttributes.Public,
                CallingConventions.Standard,
                this._constructorParameterTypes
                );

            this._packUnderlyingValueToMethodBuilder =
                this._typeBuilder.DefineMethod(
                    "PackUnderlyingValueTo",
                    MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig,
                    CallingConventions.HasThis,
                    typeof(void),
                    new[] { typeof(Packer), targetType }
                    );

            this._unpackFromUnderlyingValueMethodBuilder =
                this._typeBuilder.DefineMethod(
                    "UnpackFromUnderlyingValue",
                    MethodAttributes.Family | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig,
                    CallingConventions.HasThis,
                    targetType,
                    UnpackFromUnderlyingValueParameterTypes
                    );

            var baseType = this._typeBuilder.BaseType;
#if DEBUG
            Contract.Assert(baseType != null, "baseType != null");
#endif
            this._typeBuilder.DefineMethodOverride(
                this._packUnderlyingValueToMethodBuilder,
                baseType.GetMethod(
                    this._packUnderlyingValueToMethodBuilder.Name,
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
                    )
                );
            this._typeBuilder.DefineMethodOverride(
                this._unpackFromUnderlyingValueMethodBuilder,
                baseType.GetMethod(
                    this._unpackFromUnderlyingValueMethodBuilder.Name,
                    BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
                    )
                );
            this._isDebuggable = isDebuggable;

#if !SILVERLIGHT && !NETFX_35
            if (isDebuggable && SerializerDebugging.DumpEnabled)
            {
                SerializerDebugging.PrepareDump(host.Assembly as AssemblyBuilder);
            }
#endif
        }
예제 #22
0
        public IEnumerable <SerializerCodeGenerationResult> Generate()
        {
            Contract.Assert(this._declaringTypes != null, "_declaringTypes != null");

            using (var provider = CodeDomProvider.CreateProvider(this._configuration.Language))
            {
                var options =
                    new CodeGeneratorOptions
                {
                    BlankLinesBetweenMembers = true,
                    ElseOnClosing            = false,
                    IndentString             = this._configuration.CodeIndentString,
                    VerbatimOrder            = false
                };

                var directory =
                    Path.Combine(
                        this._configuration.OutputDirectory,
                        this._configuration.Namespace.Replace(Type.Delimiter, Path.DirectorySeparatorChar)
                        );

                var sink = this._configuration.CodeGenerationSink ?? CodeGenerationSink.ForIndividualFile();

                var result    = new List <SerializerCodeGenerationResult>(this._declaringTypes.Count);
                var extension = "." + provider.FileExtension;

                foreach (var declaringType in this._declaringTypes)
                {
                    Contract.Assert(declaringType.Value.TypeParameters.Count == 0, declaringType.Value.TypeParameters.Count + "!= 0");

                    var cn = new CodeNamespace(this._configuration.Namespace);
                    cn.Types.Add(declaringType.Value);
                    var cu = new CodeCompileUnit();
                    cu.Namespaces.Add(cn);

                    var codeInfo = new SerializerCodeInformation(declaringType.Value.Name, directory, extension);
                    sink.AssignTextWriter(codeInfo);

                    result.Add(
                        new SerializerCodeGenerationResult(
                            declaringType.Key,
                            codeInfo.FilePath,
                            String.IsNullOrEmpty(cn.Name)
                                                        ? declaringType.Value.Name
                                                        : cn.Name + "." + declaringType.Value.Name,
                            cn.Name,
                            declaringType.Value.Name
                            )
                        );

#if DEBUG
                    if (SerializerDebugging.DumpEnabled)
                    {
                        SerializerDebugging.TraceEmitEvent("Compile {0}", declaringType.Value.Name);
                    }
#endif // DEBUG

                    using (var writer =
#if DEBUG
                               SerializerDebugging.DumpEnabled
                                                        ? new TeeTextWriter(codeInfo.TextWriter ?? NullTextWriter.Instance, SerializerDebugging.ILTraceWriter) :
#endif // DEBUG
                               codeInfo.TextWriter ?? NullTextWriter.Instance
                           )
                    {
                        provider.GenerateCodeFromCompileUnit(cu, writer, options);
                        writer.WriteLine();
                        writer.Flush();

#if DEBUG
                        if (SerializerDebugging.DumpEnabled)
                        {
                            SerializerDebugging.TraceEmitEvent("Compile {0}", declaringType.Value.Name);
                            SerializerDebugging.FlushTraceData();
                        }
#endif // DEBUG
                    }
                }

                return(result);
            }
        }