Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type.GetMethod alternative for TypeBuilder

I'm making a .NET-compliant compiler using Reflection.Emit. The problem is, that although TypeBuilder is derived from Type, it does not let me use all the handy methods that Type provides.

The matters that really concern me are:

  1. Is there any way to get a list of methods, fields, properties, constructors etc. defined in a TypeBuilder, or I really have to make a TypeBuilderWrapper that keeps track of all those entities by myself? It has to store them somewhere inside, so there must be some way to extract them?

  2. The GetMethod method is very handy, because it can find the best fitting method override taking inheritance and generic covariance into account. Do I really have to reimplement it myself for the TypeBuilderWrapper?

The same issue probably applies to MethodBuilder, FieldBuilder etc. which, I believe, do not implement the lookup methods of MethodInfo and FieldInfo respectively.

like image 688
Impworks Avatar asked Jan 05 '13 16:01

Impworks


1 Answers

TypeBuilder, MethodBuilder, etc are Type, MethodInfo, but they dont have all abilities of Type, MethodInfo until you call TypeBuilder.CreateType(). The reason TypeBuilder is derived from Type is it allows you you while building class A and B, you can reference they in both directions without finishing them. Let me give an example:

// sample.x
class A {
    void method1(B b) {}
}

class B {
    void method2(A a) {}
}

So the C# code to generate class A and B would be:

// ...
// define classes
TypeBuilder classA = moduleBuilder.DefineType("A");
TypeBuilder classB = moduleBuilder.DefineType("B");

// define class A's methods
MethodBuilder method1 = classA.defineMethod("method1", MethodAttributes.Public);
method1.SetParameters(classB);
// ... build method body

// define class B's methods
MethodBuilder method2 = classB.defineMethod("method2", MethodAttributes.Public);
method1.SetParameters(classA);
// ... build method body

// finish classes
classA.CreateType();
classB.CreateType();
// this time you can use GetMethod but you can not modify classes any more. 

Answer your questions, there are no ways to get list of methods, properties, etc in TypeBuilder until you call CreateType. But you should remember these methods, properties are created by your code, so you should know them all. If you want to create some class TypeBuilderWrapper, it's your choice. But from my opinion, you should do something like:

  • Write your own models (XClass, XMethod, XParam, etc) for you X language.
  • Turn your XParser to parse the X files into language model objects.
  • Do some analysis on created models to create links between your models. For example: in sample.x above, in B.method2, parameter A a should have a link to class A model.
  • using Reflection.Emit to create the target assembly. Remember the order is: define classes, define classes' methods, define classes methods' body, etc. Then call CreateType to finish then all. The order can be changed depends on your language design.

Those are all my idea, the code might not work. When I created my simple-stupid language, I created somethings like those. Hope I could help you.

like image 180
Jacob Dam Avatar answered Nov 06 '22 13:11

Jacob Dam