예제 #1
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 DEBUG
            if (SerializerDebugging.TraceEnabled)
            {
                SerializerDebugging.FlushTraceData();
            }
#endif // DEBUG

            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();
        }
예제 #3
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();
            }
        }
        private MethodDefinition EndMethod(ILConstruct body)
        {
            ILMethodConctext lastMethod;

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

                this.IL.EmitRet();
            }
            finally
            {
                this.IL.FlushTrace();
                SerializerDebugging.FlushTraceData();
                lastMethod = this._ilGeneratorStack.Pop();
            }

            return(new MethodDefinition(lastMethod.Method, null, lastMethod.ParameterTypes));
        }
예제 #5
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);
            }
        }