WithTypeBuilder() public method

public WithTypeBuilder ( TypeBuilder tb ) : GenContext
tb System.Reflection.Emit.TypeBuilder
return GenContext
Example #1
0
        public static object Compile(GenContext context,TextReader rdr, string sourceDirectory, string sourceName, string relativePath)
        {
            object eofVal = new object();
            object form;

            string sourcePath = relativePath;

            // generate loader class
            ObjExpr objx = new ObjExpr(null);
            var internalName = sourcePath.Replace(Path.PathSeparator, '/').Substring(0, sourcePath.LastIndexOf('.'));
            objx.InternalName = internalName + "__init";

            TypeBuilder initTB = context.AssemblyGen.DefinePublicType(InitClassName(internalName), typeof(object), true);
            context = context.WithTypeBuilder(initTB);

            // static load method
            MethodBuilder initMB = initTB.DefineMethod("Initialize", MethodAttributes.Public | MethodAttributes.Static, typeof(void), Type.EmptyTypes);
            CljILGen ilg = new CljILGen(initMB.GetILGenerator());

            LineNumberingTextReader lntr = rdr as LineNumberingTextReader ?? new LineNumberingTextReader(rdr);

            Var.pushThreadBindings(RT.mapUniqueKeys(
                SourcePathVar, sourcePath,
                SourceVar, sourceName,
                MethodVar, null,
                LocalEnvVar, null,
                LoopLocalsVar, null,
                NextLocalNumVar, 0,
                RT.ReadEvalVar, true /* RT.T */,
                RT.CurrentNSVar, RT.CurrentNSVar.deref(),
                ConstantsVar, PersistentVector.EMPTY,
                ConstantIdsVar, new IdentityHashMap(),
                KeywordsVar, PersistentHashMap.EMPTY,
                VarsVar, PersistentHashMap.EMPTY,
                RT.UncheckedMathVar, RT.UncheckedMathVar.deref(),
                RT.WarnOnReflectionVar, RT.WarnOnReflectionVar.deref(),
                RT.DataReadersVar, RT.DataReadersVar.deref(),
                CompilerContextVar, context,
                CompilerActiveVar, true
                ));

            try
            {
                Object readerOpts = ReaderOpts(sourceName);

                while ((form = LispReader.read(lntr, false, eofVal, false, readerOpts)) != eofVal)
                {
                    Compile1(initTB, ilg, objx, form);
                }

                initMB.GetILGenerator().Emit(OpCodes.Ret);

                // static fields for constants
                objx.EmitConstantFieldDefs(initTB);
                MethodBuilder constInitsMB = objx.EmitConstants(initTB);

                // Static init for constants, keywords, vars
                ConstructorBuilder cb = initTB.DefineConstructor(MethodAttributes.Static, CallingConventions.Standard, Type.EmptyTypes);
                ILGenerator cbGen = cb.GetILGenerator();

                cbGen.BeginExceptionBlock();

                cbGen.Emit(OpCodes.Call,Method_Compiler_PushNS);
                cbGen.Emit(OpCodes.Call, constInitsMB);

                cbGen.BeginFinallyBlock();
                cbGen.Emit(OpCodes.Call, Method_Var_popThreadBindings);

                cbGen.EndExceptionBlock();
                cbGen.Emit(OpCodes.Ret);

                var descAttrBuilder =
                 new CustomAttributeBuilder(typeof (DescriptionAttribute).GetConstructor(new[] {typeof (String)}),
                                           new [] {String.Format("{{:clojure-namespace {0}}}", CurrentNamespace)});
                initTB.SetCustomAttribute(descAttrBuilder);

                initTB.CreateType();
            }
            catch (LispReader.ReaderException e)
            {
                throw new CompilerException(sourcePath, e.Line,  e.Column, e.InnerException);
            }
            finally
            {
                Var.popThreadBindings();
            }
            return null;
        }