Toying with making a compiler for my own language, I’m trying to generate some MSIL code using the Reflection.Emit framework. It works fine when using int when I declare local variables. However, when I want to declare a local variable of a type I have not yet compiled I get into trouble since the DeclareLocal() takes a Type as argument. That is my uncompiled class, say A, still needs to be defined using
assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemName, AssemblyBuilderAccess.RunAndSave);
module = assemblyBuilder.DefineDynamicModule(Filename);
module.DefineType(name, TypeAttributes.Public | TypeAttributes.Class)
So how will I ever be able to compile the following program
class A {
void M() { B b = new B(); }
}
class B
void M() { A a = new A(); }
}
The primary insight you need here is that
TypeBuilderderives fromType. So, even if you didn’t finalize a type yet (by callingCreateType()), you can use it to declare a local variable in another type.One more barrier I encountered is that
GetConstructor()on an unfinishedTypeBuilderdoesn’t work (it throws an exception). But if you create the default constructor explicitly, you can call it through theConstructorBuilder.