TypeResolver.cs :  » Aspect-Oriented-Frameworks » Runtime-Assembly-Instrumentation-Library » rail » Reflect » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Aspect Oriented Frameworks » Runtime Assembly Instrumentation Library 
Runtime Assembly Instrumentation Library » rail » Reflect » TypeResolver.cs
/*
  The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); 
  you may not use this file except in compliance with the License. You may obtain a copy of the License at 
  http://www.mozilla.org/MPL/ 
  Software distributed under the License is distributed on an "AS IS" basis, 
  WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language 
  governing rights and limitations under the License. 

  The Original Code is RAIL(Runtime Assembly Instrumentation Library) Alpha Version.
  The Initial Developer of the Original Code is University of Coimbra,
  Computer Science Department, Dependable Systems Group. Copyright (C) University of Coimbra. 
  All Rights Reserved.  
*/
namespace Rail.Reflect{
  using System;
  using System.Reflection;
  using System.Reflection.Emit;
  using System.Diagnostics;
  using System.Globalization;
  using System.Collections;
  using System.Runtime.InteropServices;
  
  /// <summary>
  /// Converts the Rail objects into Reflection.Emit objects
  /// </summary>
  internal sealed class TypeResolver 
  {
    /// <summary>
    /// 
    /// </summary>
    internal readonly RAssemblyDef asmRail;
    /// <summary>
    /// 
    /// </summary>
    internal readonly AssemblyBuilder asmREmit;
    /// <summary>
    /// 
    /// </summary>
    private Hashtable TypeBuilders;
    /// <summary>
    /// 
    /// </summary>
    private Hashtable MethodBuilders;
    /// <summary>
    /// 
    /// </summary>
    private Hashtable ConstructorBuilders;
    /// <summary>
    /// 
    /// </summary>
    private Hashtable FieldBuilders;
    /// <summary>
    /// 
    /// </summary>
    private Hashtable PropertyBuilders;
    /// <summary>
    /// 
    /// </summary>
    private Hashtable EventBuilders;
    /// <summary>
    /// 
    /// </summary>
    private Hashtable CustomAttributeBuilders;

    /// <summary>
    /// Creates a TypeResolver using the context defined by the given <code>RAssembly</code> 
    /// and <code>AssemblyBuilder</code>.
    /// </summary>
    /// <param name="asmRail"></param>
    /// <param name="asmREmit"></param>
    public TypeResolver(RAssemblyDef asmRail, AssemblyBuilder asmREmit) 
    {
      if (asmRail == null)
        throw new InvalidProgramException();
      if (asmREmit == null)
        throw new InvalidProgramException();
      this.asmRail = asmRail;
      this.asmREmit = asmREmit;    
      this.TypeBuilders = new Hashtable();
      this.MethodBuilders = new Hashtable();
      this.ConstructorBuilders = new Hashtable();
      this.FieldBuilders = new Hashtable();
      this.TypeBuilders = new Hashtable();
      this.PropertyBuilders = new Hashtable();
      this.EventBuilders = new Hashtable();
      this.CustomAttributeBuilders = new Hashtable();
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="assmDef"></param>
    /// <param name="abAccess"></param>
    /// <returns></returns>
    public static AssemblyBuilder ResolveRAssembly(RAssemblyDef assmDef, AssemblyBuilderAccess abAccess)
    {
      AssemblyBuilder assmBldr = null;  
      AssemblyBuilderAccess access = abAccess;
      AssemblyName assemblyName = new AssemblyName();
      assemblyName.Name = assmDef.Name.Name;
      assemblyName.Version = new Version(assmDef.Name.Version.Major,assmDef.Name.Version.Minor,assmDef.Name.Version.Build,assmDef.Name.Version.Revision);
      //FIX : Hot to get the culture number by the name
      //TODO : read the correct culture code from the assembly and create a valid cultureinfo object
      assemblyName.CultureInfo = CultureInfo.InvariantCulture;
      if (assmDef.Name.PublicKeyToken!=null)
        assemblyName.SetPublicKeyToken(assmDef.Name.PublicKeyToken);
      else assemblyName.SetPublicKeyToken(null);
      assmBldr = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,access,"..\\");  
      //END OF FIX
      return assmBldr;
    }

    /// <summary>
    /// Resolves the RModuleDef into a ModuleBuilder
    /// </summary>
    /// <param name="module"></param>
    /// <returns></returns>
    public Module ResolveRModule(RModuleDef module) 
    {
      string moduleFileName = module.FileName;
      string moduleName = module.Name;
      Module m = this.asmREmit.GetModule(moduleName);
      if (m == null)
      {
        ModuleBuilder moduleBuilder = asmREmit.DefineDynamicModule(moduleName,moduleFileName,true);
        m = (Module) moduleBuilder;
      }
      return m;
    }

    /// <summary>
    /// Resolves the RModuleDef into a ModuleBuilder
    /// </summary>
    /// <param name="module"></param>
    /// <param name="filename"></param>
    /// <returns></returns>
    public Module ResolveRModule(RModuleDef module, string filename) 
    {
      string moduleFileName = filename;
      string moduleName = filename;
      module.Name = filename;
      module.FileName = filename;
    
      Module m = this.asmREmit.GetModule(moduleName);
      if (m == null)
      {
        ModuleBuilder moduleBuilder = asmREmit.DefineDynamicModule(moduleName,moduleFileName,true);
        m = (Module) moduleBuilder;
      }
      return m;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public Type ResolveRType(RType type)
    {
      if (type is RTypeDef)
        return ResolveRTypeDef((RTypeDef)type);
      else
        return ResolveRTypeRef((RTypeRef)type);
    }
    /// <summary>
    /// Resolves the RTypeRef into a Type
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public Type ResolveRTypeRef(RTypeRef type) 
    {
      int resolutionScope = type.ResolutionScope & 0x00000003;
      if (resolutionScope==0x02 || resolutionScope==0x0) 
      {        
        Type retType = type.ReflectionType;
        if (retType==null)
        {
          retType =Type.GetType(type.NameWithNameSpace);
          if (retType == null)
          {
          
            System.Reflection.Assembly asbly;

            if (type.Assembly == null) {
              // KIRK: Types in the current assembly don't have an assembly set
              asbly = Assembly.GetExecutingAssembly();
              if (asbly!=null)
                retType = asbly.GetType(type.NameWithNameSpace);
              if (retType == null) {
                foreach (System.Reflection.Assembly a in AppDomain.CurrentDomain.GetAssemblies()) {
                  retType = a.GetType(type.NameWithNameSpace);
                  if (retType != null) break;
                }
              }
            } 
            if (retType == null)
            {
              if (type.NameWithNameSpace.IndexOf("&")>0)
              {
                //TODO: this is a workaroun until the complete problem is not solved
                RType rTempT = this.asmRail.GetType(type.NameWithNameSpace.Substring(0,type.NameWithNameSpace.Length-1));
                if (rTempT==null)
                  rTempT = this.asmRail.RModuleDef.GetType(type.NameWithNameSpace.Substring(0,type.NameWithNameSpace.Length-1));
                Type tempT = ResolveRType(rTempT);
                retType =  this.asmREmit.GetDynamicModule(this.asmRail.RModuleDef.Name).GetType(type.NameWithNameSpace);
              
              }
              if (retType == null)
              {
                throw new NullReferenceException("Type not found");
              }
            }
          }
        }
        return retType;
      }
      else if (resolutionScope==0x03) 
      {
        RTypeRef rtr = this.asmRail.GetTypeByToken((type.ResolutionScope>>2));
        if (rtr==null)
          throw new NullReferenceException("BAD referenced type");
        Type referencedType = ResolveRTypeRef(rtr);
        //TODO: Check this binding flags
        BindingFlags bindingFlags = BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static;
        Type typeToReturn = referencedType.GetNestedType(type.Name,bindingFlags);
        if (typeToReturn==null)
          throw new NullReferenceException("Nested type not found");
        return typeToReturn;
      }
      else 
      {
        throw new Exception("Resolution scope error");
      }
    }

    /// <summary>
    /// Resolves the RTypeDef into a TypeBuilder
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public Type ResolveRTypeDef(RTypeDef type) 
    {
      string typeName = type.FullName;

      Type [] moduleTypes = ResolveRModule(this.asmRail.RModuleDef).GetTypes();
      Type returnType = null;
      for (int i=0;i<moduleTypes.Length;i++) 
      {
        string assemblyQualifiedName = moduleTypes[i].AssemblyQualifiedName;
        if (String.CompareOrdinal(typeName,0,assemblyQualifiedName,0,typeName.Length)==0) 
        {
          returnType = moduleTypes[i];
          break;
        }
      }
      if (returnType==null)
      {
        if (this.TypeBuilders == null)
          this.TypeBuilders = new Hashtable();
        if (this.TypeBuilders.Contains(type.NameWithNameSpace))
          returnType = (Type)(this.TypeBuilders[type.NameWithNameSpace]);
        if (returnType==null)
        {
          RType [] rTypeInterfaces = type.GetInterfaces();
          Type t = null;
          if (type.IsArray)
          {
            returnType = ResolveRModule(this.asmRail.RModuleDef).GetType(type.NameWithNameSpace) as Type;
          }
          else if (type.IsNested && type.DeclaringType!=null 
            && type.BaseType!=null && type.BaseType.NameWithNameSpace.Equals("System.Enum"))
          {
            TypeBuilder tParentEnum = (TypeBuilder)ResolveRType(type.DeclaringType);
            t = (TypeBuilder)tParentEnum.DefineNestedType(type.Name, 
              type.Attributes, 
              typeof(System.Enum), type.TypeSize);
            foreach(RFieldDef f in type.GetFields())
            {
              Type ft;
              if (type.FullName.Equals(f.FieldType.FullName))
                ft = t;
              else
                ft = ResolveRType(f.FieldType);
              FieldBuilder fb = ((TypeBuilder)t).DefineField(
                  f.Name,
                  ft,
                  f.Attributes);
              if ((f.Value != null) && (f.Name != "value__"))
                fb.SetConstant(f.Value);
              if (f.HasMarshal)
              {
                
                if (f.MarshalSpec.GetNativeType() == UnmanagedType.ByValArray)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineByValArray(f.MarshalSpec.NumElem));  
                }
                else if (f.MarshalSpec.GetNativeType() == UnmanagedType.ByValTStr)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineByValTStr(f.MarshalSpec.NumElem));  
                }
                else if (f.MarshalSpec.GetNativeType() == UnmanagedType.LPArray)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineLPArray(f.MarshalSpec.ArrayElementType));  
                }
                else if (f.MarshalSpec.GetNativeType() == UnmanagedType.SafeArray)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineSafeArray(f.MarshalSpec.ArrayElementType));  
                }
                else
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineUnmanagedMarshal(f.MarshalSpec.GetNativeType()));  
                }
              }
              if (f.Offset>0)
                ((FieldBuilder)fb).SetOffset(f.Offset);
            }

          }
          else if (type.IsNested && type.DeclaringType!=null &&
            type.BaseType!=null && type.BaseType.NameWithNameSpace.Equals("System.MulticastDelegate"))
          {
            TypeBuilder tParentDelegate = (TypeBuilder)ResolveRType(type.DeclaringType);
            t = (TypeBuilder)tParentDelegate.DefineNestedType(
              type.Name,
              type.Attributes,
              typeof(System.MulticastDelegate),type.TypeSize);
          }
          else if (type.IsNested && type.DeclaringType!=null) 
          {
            
            TypeBuilder tParent = (TypeBuilder)ResolveRType(type.DeclaringType);
            t = (TypeBuilder)tParent.DefineNestedType(type.Name,type.Attributes,null,type.TypeSize);
          }
          else if (type.BaseType!=null && type.BaseType.NameWithNameSpace.Equals("System.Enum"))
          {
//            ///TODO: There is a problem with the literals attributes, but Reflection.Emit 

            t = (TypeBuilder)((ModuleBuilder)ResolveRModule(this.asmRail.RModuleDef)).DefineType(type.NameWithNameSpace, 
              type.Attributes, 
              typeof(System.Enum), type.TypeSize);
            foreach(RFieldDef f in type.GetFields())
            {
              Type ft;
              if (type.FullName.Equals(f.FieldType.FullName))
                ft = t;
              else
                ft = ResolveRType(f.FieldType);

              FieldBuilder fb = ((TypeBuilder)t).DefineField(
                f.Name,
                ft,
                f.Attributes);
              if ((f.Value != null) && (f.Name != "value__"))
                fb.SetConstant(f.Value);
              if (f.HasMarshal)
              {
                
                if (f.MarshalSpec.GetNativeType() == UnmanagedType.ByValArray)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineByValArray(f.MarshalSpec.NumElem));  
                }
                else if (f.MarshalSpec.GetNativeType() == UnmanagedType.ByValTStr)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineByValTStr(f.MarshalSpec.NumElem));  
                }
                else if (f.MarshalSpec.GetNativeType() == UnmanagedType.LPArray)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineLPArray(f.MarshalSpec.ArrayElementType));  
                }
                else if (f.MarshalSpec.GetNativeType() == UnmanagedType.SafeArray)
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineSafeArray(f.MarshalSpec.ArrayElementType));  
                }
                else
                {
                  ((FieldBuilder)fb).SetMarshal(UnmanagedMarshal.DefineUnmanagedMarshal(f.MarshalSpec.GetNativeType()));  
                }
              }
              if (f.Offset>0)
                ((FieldBuilder)fb).SetOffset(f.Offset);
            }
          }
          else if (type.BaseType!=null && type.BaseType.NameWithNameSpace.Equals("System.MulticastDelegate"))
          {
            t = (TypeBuilder)((ModuleBuilder)ResolveRModule(this.asmRail.RModuleDef)).DefineType(
              type.NameWithNameSpace,
              type.Attributes,
              typeof(System.MulticastDelegate),type.TypeSize);
          }
          else if ((rTypeInterfaces != null) && (rTypeInterfaces.Length > 0)) {
            // KIRK: Added this case to include interfaces in defineType call
            Type [] interfaces = new Type[rTypeInterfaces.Length];
            for (int i = 0; i< rTypeInterfaces.Length;i++)
              interfaces[i] = ResolveRType(rTypeInterfaces[i]);
            
            // This call doesn't have type.TypeSize -- is that a problem???
            t = (TypeBuilder)((ModuleBuilder)ResolveRModule(this.asmRail.RModuleDef)).DefineType(
              type.NameWithNameSpace,
              type.Attributes,null,interfaces);
          }
          else
          {
            t = (TypeBuilder)((ModuleBuilder)ResolveRModule(this.asmRail.RModuleDef)).DefineType(
              type.NameWithNameSpace,
              type.Attributes,null,type.TypeSize);
          }
          if (t!=null)
          {
            if (type.BaseType!=null)
              if (t is TypeBuilder)
              {
                ((TypeBuilder)t).SetParent(ResolveRType(type.BaseType)); 
              }
            if (rTypeInterfaces!=null && t is TypeBuilder)
            {
              for (int i = 0; i< rTypeInterfaces.Length;i++)
              {
                ((TypeBuilder)t).AddInterfaceImplementation(ResolveRType(rTypeInterfaces[i]));
              }
            }
            returnType = (Type)t;
            this.TypeBuilders.Add(type.NameWithNameSpace,t);
          }
        }
      }  
      return returnType;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="field"></param>
    /// <returns></returns>
    public FieldInfo ResolveRField(RField field) 
    {
      Type fieldType = ResolveRType(field.FieldType);
      Type type = (Type)ResolveRType(field.DeclaringType);
      BindingFlags bf = (BindingFlags) BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | 
        BindingFlags.Instance;
      FieldInfo fi = null;
      //TODO:Verify if it has beeen created???
      if (field is RFieldRef)
        fi = type.GetField(field.Name,bf);
      else if (field is RFieldDef)
        if (fi==null)
        {
          if (this.FieldBuilders == null)
            this.FieldBuilders = new Hashtable();
          if (this.FieldBuilders.Contains(field.DeclaringType.NameWithNameSpace+field.Name+field.FieldType.NameWithNameSpace))
            fi = (FieldInfo)((FieldBuilder)this.FieldBuilders[field.DeclaringType.NameWithNameSpace+field.Name+field.FieldType.NameWithNameSpace]);
          if (fi==null)
          {
              fi = (FieldInfo)((TypeBuilder)type).DefineField(field.Name,fieldType,field.Attributes);
            if (fi!=null)
            {
              if (field.Value!=null)
                try
                {
                  // KIRK: Change int to Enum if necessary
                  if ((fi.FieldType.UnderlyingSystemType != null) && (fi.FieldType.UnderlyingSystemType.BaseType != null) &&
                    (fi.FieldType.UnderlyingSystemType.BaseType.FullName == "System.Enum")) {
                    ((FieldBuilder)fi).SetConstant(Enum.ToObject(fi.FieldType.UnderlyingSystemType, field.Value));
                  } else if ((field.FieldType.BaseType != null) && (field.FieldType.BaseType.NameWithNameSpace == "System.Enum")) {
                    if (field.FieldType is RTypeRef) {
                      ((FieldBuilder)fi).SetConstant(Convert.ChangeType(field.Value, ((RTypeRef)field.FieldType).reflectionType));
                    }
                  } else {
                    ((FieldBuilder)fi).SetConstant(field.Value);
                  }                
                }
                catch (System.ArgumentException ex)
                {
                  Console.WriteLine("It Was not possible to add a default value to the field");
                  Console.WriteLine(ex.StackTrace);
                }
              if (field.HasMarshal)
              {
                
                if (field.MarshalSpec.GetNativeType() == UnmanagedType.ByValArray)
                {
                  ((FieldBuilder)fi).SetMarshal(UnmanagedMarshal.DefineByValArray(field.MarshalSpec.NumElem));  
                }
                else if (field.MarshalSpec.GetNativeType() == UnmanagedType.ByValTStr)
                {
                  ((FieldBuilder)fi).SetMarshal(UnmanagedMarshal.DefineByValTStr(field.MarshalSpec.NumElem));  
                }
                else if (field.MarshalSpec.GetNativeType() == UnmanagedType.LPArray)
                {
                  ((FieldBuilder)fi).SetMarshal(UnmanagedMarshal.DefineLPArray(field.MarshalSpec.ArrayElementType));  
                }
                else if (field.MarshalSpec.GetNativeType() == UnmanagedType.SafeArray)
                {
                  ((FieldBuilder)fi).SetMarshal(UnmanagedMarshal.DefineSafeArray(field.MarshalSpec.ArrayElementType));  
                }
                else
                {
                  ((FieldBuilder)fi).SetMarshal(UnmanagedMarshal.DefineUnmanagedMarshal(field.MarshalSpec.GetNativeType()));  
                }
              }
              if (((RFieldDef)field).Offset>0)
                ((FieldBuilder)fi).SetOffset(((RFieldDef)field).Offset);
            }
            this.FieldBuilders.Add(field.DeclaringType.NameWithNameSpace+field.Name+field.FieldType.NameWithNameSpace,fi);
          }
        }
      //TODO:Check if it is necessary to get the constant value


      return fi;
    }
    
    /// <summary>
    /// 
    /// </summary>    
    /// <param name="method"></param>
    /// <returns></returns>
    public MethodInfo ResolveRMethod(RMethod method) 
    {
      Type type = ResolveRType(method.DeclaringType);
      BindingFlags bindingFlags = BindingFlags.Instance
        | BindingFlags.NonPublic
        | BindingFlags.Public
        | BindingFlags.Static;
      RParameter [] pt = method.GetParameters();
      Type [] paramTypes = null;
      if (pt != null)
      {
        paramTypes = new Type[pt.Length];
        for (int i=0; i< pt.Length;i++)
        {
          paramTypes[i] = ResolveRType(pt[i].ParameterType);
        }
      }
      MethodInfo mi = null;
      if (method is RMethodRef){

        // KIRK: GetMethod may break if methods only differ by return type
        try {
          mi = type.GetMethod(method.Name,bindingFlags,null,method.CallingConventions,paramTypes,null);
        } catch (AmbiguousMatchException) {
          // If there is an ambiguous match, it's probably due to return type overloading
          // (e.g. IntPtr.op_Explicit(IntPtr))
          MethodInfo[] methods = type.GetMethods(bindingFlags);
          foreach (MethodInfo mis in methods) {
            if ((mis.Name == method.Name) &&
              (mis.ReturnType.FullName == method.ReturnType.ReturnType.NameWithNameSpace)) {

              // This might be it - check params
              ParameterInfo[] misParams = mis.GetParameters();
              RParameter[] methodParams = method.GetParameters();
              if (misParams.Length == methodParams.Length) {
                bool success = true;
                for (int i = 0; i < misParams.Length; i++) {
                  if (misParams[i].ParameterType.FullName !=
                    methodParams[i].ParameterType.NameWithNameSpace) {
                    success = false;
                    break;
                  }
                }
                if (success) {
                  mi = mis;
                  break;
                }
              }
            }
          }
          if (mi == null)
            throw;
        }
      } else if (method is RMethodDef)
        if (mi==null)
        {
          if (this.MethodBuilders == null)
            this.MethodBuilders = new Hashtable();
          if (this.MethodBuilders.Contains(method.Name+
            method.DeclaringType.NameWithNameSpace+
            method.ReturnType.ReturnType.NameWithNameSpace+
            ParamsToString(paramTypes)))
            mi = (MethodInfo)((MethodBuilder)this.MethodBuilders[method.Name+
              method.DeclaringType.NameWithNameSpace+
              method.ReturnType.ReturnType.NameWithNameSpace+
              ParamsToString(paramTypes)]);
          if (mi==null)
          {
            if (method.IsPInvoke)
            {
              mi = (MethodInfo)((TypeBuilder)type).DefinePInvokeMethod(
                method.Name,
                method.PInvokeInfo.DLLName,
                method.PInvokeInfo.EntryName,
                method.Attributes,
                method.CallingConventions,
                ResolveRType(method.ReturnType.ReturnType),
                paramTypes,
                method.PInvokeInfo.NativeCallingConvention,
                method.PInvokeInfo.NativeCharSet);
            }
            else
            {
              mi = (MethodInfo)((TypeBuilder)type).DefineMethod(
                method.Name,method.Attributes,
                method.CallingConventions,
                ResolveRType(method.ReturnType.ReturnType),
                paramTypes);
            }
            RParameter [] rParam = method.GetParameters();
            RCustomAttrib rca;
            if (rParam!=null)
              for (int pIndex=0; pIndex<rParam.Length;pIndex++)
              {
                RParameter tempParam = rParam[pIndex];
                int newSeq = tempParam.Sequence;
                if ((mi.Attributes & MethodAttributes.Static)!=0)
                  ++newSeq;
                ParameterBuilder pb = ((MethodBuilder)mi).DefineParameter(newSeq,
                  tempParam.Attributes,tempParam.Name);
                if (tempParam.CustomAttributeCount>0)
                  while (tempParam.MoveToNextCustomAttribute())
                  {
                    rca = null;
                    rca = tempParam.CurrentCustomAttribute;
                    if (rca!=null && rca.GetAttributeConstructorArguments()!=null)
                      pb.SetCustomAttribute(ResolveRCustomAttrib(rca));
                    else if (rca!=null)
                    {
                      ConstructorInfo cInfo = ResolveRConstructor(rca.AttributeConstructor) as ConstructorInfo;
                      pb.SetCustomAttribute(cInfo,rca.AttributeData);
                    }
                  }
                
                if (rParam[pIndex].HasMarshal)
                {
                
                  if (rParam[pIndex].MarshalSpec.GetNativeType() == UnmanagedType.ByValArray)
                  {
                    ((ParameterBuilder)pb).SetMarshal(UnmanagedMarshal.DefineByValArray(rParam[pIndex].MarshalSpec.NumElem));  
                  }
                  else if (rParam[pIndex].MarshalSpec.GetNativeType() == UnmanagedType.ByValTStr)
                  {
                    ((ParameterBuilder)pb).SetMarshal(UnmanagedMarshal.DefineByValTStr(rParam[pIndex].MarshalSpec.NumElem));  
                  }
                  else if (rParam[pIndex].MarshalSpec.GetNativeType() == UnmanagedType.LPArray)
                  {
                    ((ParameterBuilder)pb).SetMarshal(UnmanagedMarshal.DefineLPArray(rParam[pIndex].MarshalSpec.ArrayElementType));  
                  }
                  else if (rParam[pIndex].MarshalSpec.GetNativeType() == UnmanagedType.SafeArray)
                  {
                    ((ParameterBuilder)pb).SetMarshal(UnmanagedMarshal.DefineSafeArray(rParam[pIndex].MarshalSpec.ArrayElementType));  
                  }
                  else
                  {
                    ((ParameterBuilder)pb).SetMarshal(UnmanagedMarshal.DefineUnmanagedMarshal(rParam[pIndex].MarshalSpec.GetNativeType()));  
                  }
                }
              }
            if (mi!=null 
              && mi.DeclaringType!=null 
              && mi.DeclaringType.BaseType != null 
              && mi.DeclaringType.BaseType.FullName.Equals("System.MulticastDelegate"))
              ((MethodBuilder)mi).SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
            this.MethodBuilders.Add(method.Name+
            method.DeclaringType.NameWithNameSpace+
            method.ReturnType.ReturnType.NameWithNameSpace+
            ParamsToString(paramTypes),mi);
          }
        }
      if (mi==null)
        throw new NullReferenceException("No MethodInfo found");
      return mi;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="declaration"></param>
    /// <param name="body"></param>
    public void DefineMethodOverride(MethodInfo declaration, MethodInfo body)
    {
      TypeBuilder tb = body.DeclaringType as TypeBuilder;
      tb.DefineMethodOverride(body,declaration);
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="method"></param>
    /// <returns></returns>
    public ConstructorInfo ResolveRConstructor(RConstructor method) 
    {
      Type type = ResolveRType(method.DeclaringType);
      BindingFlags bindingFlags = BindingFlags.NonPublic
        | BindingFlags.Public;
      ConstructorInfo ci = null;
      if ( method.Name == ".ctor" ) 
      {
        bindingFlags = BindingFlags.Instance
          | BindingFlags.NonPublic
          | BindingFlags.Public;
      } 
      else if ( method.Name == ".cctor" ) 
      {
        bindingFlags = BindingFlags.Static
          | BindingFlags.NonPublic
          | BindingFlags.Public;
        
      } 
      RParameter [] pt = method.GetParameters();
      Type [] paramTypes = null;
      if (pt != null)
      {
        paramTypes = new Type[pt.Length];
        int j = 0;
        for (int i=0; i< pt.Length;i++)
        {
          //TODO: Verify why a null parameter is appearing
          if (pt[i].ParameterType==null)
          {
            Type [] temp = new Type[paramTypes.Length-1];
            for (int x = 0; x < i;x++)
              temp[x] = paramTypes[x];
            paramTypes = temp;
          }
          else
          {
            paramTypes[j] = ResolveRType(pt[i].ParameterType);
            j++;
          }
        }
      }
      //TODO:Verify if it has beeen created???
      if (method is RConstructorRef)
        ci = type.GetConstructor(bindingFlags,null, paramTypes,null);
      else if (method is RConstructorDef)
        if (ci==null)
        {
          if (this.ConstructorBuilders == null)
            this.ConstructorBuilders = new Hashtable();
          if (this.ConstructorBuilders.Contains(method.DeclaringType.NameWithNameSpace+
            method.Attributes.ToString()+
            method.CallingConventions.ToString()+
            ParamsToString(paramTypes)))
            ci = (ConstructorInfo)((ConstructorBuilder)this.ConstructorBuilders[method.DeclaringType.NameWithNameSpace+
              method.Attributes.ToString()+
              method.CallingConventions.ToString()+
              ParamsToString(paramTypes)]);
          if (ci==null)
          {
            RCustomAttrib rca;
            ci = (ConstructorInfo)((TypeBuilder)type).DefineConstructor(method.Attributes,method.CallingConventions,paramTypes);

            // KIRK: InternalCall methods don't have (or need) IL for the method body.
            // We need to copy MethodImplementationFlags to allow this, but they currently
            // aren't preserved by the writer when constructing the new assembly.
            if ((method.MethodImplementationFlags & MethodImplAttributes.InternalCall) == 
              MethodImplAttributes.InternalCall) {
              Type ConstructorBuilderType = typeof(ConstructorBuilder);
              FieldInfo mbfi = ConstructorBuilderType.GetField("m_methodBuilder", BindingFlags.Instance | BindingFlags.NonPublic);
              MethodBuilder mb = (MethodBuilder)mbfi.GetValue(ci);

              Type MethodBuilderType = typeof(MethodBuilder);
              FieldInfo iffi = MethodBuilderType.GetField("m_dwMethodImplFlags", BindingFlags.Instance | BindingFlags.NonPublic);
              iffi.SetValue(mb, method.MethodImplementationFlags);
            }

            RParameter [] rParam = method.GetParameters();
            if (rParam!=null)
              for (int pIndex=0; pIndex<rParam.Length;pIndex++)
              {
                RParameter tempParam = rParam[pIndex];
                ParameterBuilder pb =
                ((ConstructorBuilder)ci).DefineParameter(tempParam.Sequence,
                  tempParam.Attributes,tempParam.Name);
                if (tempParam.CustomAttributeCount>0)
                  while (tempParam.MoveToNextCustomAttribute())
                  {
                    rca = null;
                    rca = tempParam.CurrentCustomAttribute;
                    if (rca!=null && rca.GetAttributeConstructorArguments()!=null)
                      pb.SetCustomAttribute(ResolveRCustomAttrib(rca));
                    else if (rca!=null)
                    {
                      ConstructorInfo cInfo = ResolveRConstructor(rca.AttributeConstructor) as ConstructorInfo;
                      pb.SetCustomAttribute(cInfo,rca.AttributeData);
                    }
                  }
              }
            if (ci != null
              && ci.DeclaringType != null
              && ci.DeclaringType.BaseType != null
              && ci.DeclaringType.BaseType.FullName.Equals("System.MulticastDelegate"))
              ((ConstructorBuilder)ci).SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);

            this.ConstructorBuilders.Add(method.DeclaringType.NameWithNameSpace+
              method.Attributes.ToString()+
              method.CallingConventions.ToString()+
              ParamsToString(paramTypes),ci);
          }
          
        }
      if (ci==null)
        throw new NullReferenceException("No ConstructorInfo found");
      return ci;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="types"></param>
    /// <returns></returns>
    private string ParamsToString(Type [] types)
    {
      string returnString = "";
      if (types!=null)
        for (int i = 0; i < types.Length; i++)
        {
          returnString += types[i].Namespace + "." + types[i].Name + "-";
        }
      return returnString;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="rp"></param>
    /// <returns></returns>
//    public PropertyBuilder ResolveRProperty(RProperty rp)
//    {
//      TypeBuilder tb = (TypeBuilder)ResolveRType(rp.DeclaringType);
//      Type pt = ResolveRType(rp.PropertyType);
//      RParameter [] rParams = rp.GetIndexParameters();
//      Type [] parameters = null;
//      if (rParams!=null)
//      {
//        parameters = new Type[rParams.Length];
//        for (int i=0;i<rParams.Length;i++)
//        {
//          parameters[i] = ResolveRType(rParams[i].ParameterType);
//        }
//      }
//      PropertyBuilder propertyBuilder = null;
//      if (this.PropertyBuilders==null)
//        this.PropertyBuilders = new Hashtable();
//            if (this.PropertyBuilders.Contains(rp.Name+
//        rp.DeclaringType.NameWithNameSpace+
//        rp.PropertyType.NameWithNameSpace))
//        propertyBuilder = (PropertyBuilder)this.PropertyBuilders[rp.Name+
//        rp.DeclaringType.NameWithNameSpace+
//        rp.PropertyType.NameWithNameSpace];
//      if (propertyBuilder==null)
//      {
//        propertyBuilder = tb.DefineProperty(
//          rp.Name,
//          rp.Attributes,
//          pt,
//          parameters);
//        if (propertyBuilder==null)
//          throw new NullReferenceException("RProperty not correctly resolved before setting the methods");
//        RMethod rm = rp.GetMethod;
//        if (rm!=null)
//        {
//          MethodBuilder mb = (MethodBuilder)ResolveRMethod(rm);
//          propertyBuilder.SetGetMethod(mb);
//        }
//        rm = null;
//        rm = rp.SetMethod;
//        if (rm!=null)
//        {
//          MethodBuilder mb = (MethodBuilder)ResolveRMethod(rm);
//          propertyBuilder.SetSetMethod(mb);
//        }
//        this.PropertyBuilders.Add(rp.Name+
//          rp.DeclaringType.NameWithNameSpace+
//          rp.PropertyType.NameWithNameSpace,propertyBuilder);
//      }
//      if (propertyBuilder==null)
//        throw new NullReferenceException("RProperty not correctly resolved");
//      return propertyBuilder;
//    }

    public PropertyInfo ResolveRProperty(RProperty rp)
    {
      Type tb = (Type)ResolveRType(rp.DeclaringType);
      Type pt = ResolveRType(rp.PropertyType);
      RParameter [] rParams = rp.GetIndexParameters();
      Type [] parameters = null;
      if (rParams!=null)
      {
        parameters = new Type[rParams.Length];
        for (int i=0;i<rParams.Length;i++)
        {
          parameters[i] = ResolveRType(rParams[i].ParameterType);
        }
      }
      if (tb is TypeBuilder)
      {
        PropertyBuilder propertyBuilder = null;
        if (this.PropertyBuilders==null)
          this.PropertyBuilders = new Hashtable();
        if (this.PropertyBuilders.Contains(rp.Name+
          rp.DeclaringType.NameWithNameSpace+
          rp.PropertyType.NameWithNameSpace))
          propertyBuilder = (PropertyBuilder)this.PropertyBuilders[rp.Name+
            rp.DeclaringType.NameWithNameSpace+
            rp.PropertyType.NameWithNameSpace];
        if (propertyBuilder==null)
        {
          propertyBuilder = ((TypeBuilder)tb).DefineProperty(
            rp.Name,
            rp.Attributes,
            pt,
            parameters);
          if (propertyBuilder==null)
            throw new NullReferenceException("RProperty not correctly resolved before setting the methods");
          RMethod rm = rp.GetMethod;
          if (rm!=null)
          {
            MethodBuilder mb = (MethodBuilder)ResolveRMethod(rm);
            propertyBuilder.SetGetMethod(mb);
          }
          rm = null;
          rm = rp.SetMethod;
          if (rm!=null)
          {
            MethodBuilder mb = (MethodBuilder)ResolveRMethod(rm);
            propertyBuilder.SetSetMethod(mb);
          }
          this.PropertyBuilders.Add(rp.Name+
            rp.DeclaringType.NameWithNameSpace+
            rp.PropertyType.NameWithNameSpace,propertyBuilder);
        }
        if (propertyBuilder==null)
          throw new NullReferenceException("RProperty not correctly resolved");
        return (PropertyInfo)propertyBuilder;
      }
      else
      {
        return tb.GetProperty(rp.Name,pt);
      }
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="re"></param>
    /// <returns></returns>
    public EventBuilder ResolveREvent(REventDef re)
    {
      TypeBuilder tb = (TypeBuilder)ResolveRType(re.DeclaringType);
      Type et = ResolveRType(re.EventType);
      EventBuilder eventBuilder=null;
      if (this.EventBuilders==null)
        this.EventBuilders = new Hashtable();
      if (this.EventBuilders.Contains(re.Name+
        re.DeclaringType.NameWithNameSpace+
        re.EventType.NameWithNameSpace))
        eventBuilder = (EventBuilder)this.EventBuilders[re.Name+
          re.DeclaringType.NameWithNameSpace+
          re.EventType.NameWithNameSpace];
      if (eventBuilder==null)
      {
        eventBuilder = tb.DefineEvent(
          re.Name,
          re.Attributes,
          et);
        if (eventBuilder==null)
          throw new NullReferenceException("The REvent was not correctly resolved before setting the methods");
        RMethod rm = null;
        rm = re.RaiseMethod;
        if (rm != null)
        {
          MethodBuilder mb = (MethodBuilder)ResolveRMethod(rm);
          eventBuilder.SetRaiseMethod(mb);
        }
        rm = null;
        rm = re.AddOnMethod;
        if (rm != null)
        {
          MethodBuilder mb = (MethodBuilder)ResolveRMethod(rm);
          eventBuilder.SetAddOnMethod(mb);
        }
        rm = null;
        rm = re.RemoveOnMethod;
        if (rm != null)
        {
          MethodBuilder mb = (MethodBuilder)ResolveRMethod(rm);
          eventBuilder.SetRemoveOnMethod(mb);
        }
        this.EventBuilders.Add(re.Name+
          re.DeclaringType.NameWithNameSpace+
          re.EventType.NameWithNameSpace,eventBuilder);
      }
      if (eventBuilder==null)
        throw new NullReferenceException("The REvent was not correctly resolved");
      return eventBuilder;
    }

    public CustomAttributeBuilder ResolveRCustomAttrib(RCustomAttrib cAttrib)
    {
      Object [] ConstructorArgs = cAttrib.GetAttributeConstructorArguments();
      ConstructorInfo con = ResolveRConstructor(cAttrib.AttributeConstructor);
      PropertyInfo[] namedProperties = null;
      object[] propertyValues = cAttrib.GetPropertiesValues();
      FieldInfo[] namedFields = null;
      object[] fieldValues = cAttrib.GetFieldsValues();
      RProperty [] properties = cAttrib.GetProperties();
      RField [] fields = cAttrib.GetFields();
      if (properties!=null &&
        properties.Length>0 &&
        properties.Length == propertyValues.Length)
      {
        namedProperties = new PropertyInfo[properties.Length];
        int i = 0;
        while (i<properties.Length)
        {
          namedProperties[i] = ResolveRProperty(properties[i]) as PropertyInfo;
          ++i;
        }
      }
      if (fields!=null &&
        fields.Length>0 &&
        fields.Length == fieldValues.Length)
      {
        namedFields = new FieldInfo[fields.Length];
        int i = 0;
        while (i<fields.Length)
        {
          namedFields[i] = ResolveRField(fields[i]) as FieldInfo;
          ++i;
        }
      }

      int j = 0;
      if (ConstructorArgs!=null)
        while (j<ConstructorArgs.Length)
        {
          if (ConstructorArgs[j] is RType)
            ConstructorArgs[j] = ResolveRType((RType)ConstructorArgs[j]);
          ++j;
        }

      CustomAttributeBuilder cAttribBuilder = null;
      
      // KIRK: If con.Attributes is private, we can't create it - so remove the 'private' from the Attributes
      if ((con.Attributes & MethodAttributes.Private) == MethodAttributes.Private) {
        Type conBuilderType = con.GetType();
        object ret = conBuilderType.InvokeMember("m_methodBuilder", BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance, null, con, new object[] {});
        if (ret != null) {
          Type methodBuilderType = ret.GetType();
          object attr = methodBuilderType.InvokeMember("m_iAttributes", 
            BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance, 
            null, 
            ret, new object[] {});
          
          if (attr != null) {
            FieldInfo fi = methodBuilderType.GetField("m_iAttributes", 
              BindingFlags.GetField | BindingFlags.NonPublic | BindingFlags.Instance);
            fi.SetValue(ret, con.Attributes ^ MethodAttributes.Private);
          }
        }
      }

      if (fieldValues!=null && propertyValues!=null && fieldValues.Length>0 && propertyValues.Length>0)
        cAttribBuilder = new CustomAttributeBuilder(con,ConstructorArgs,namedProperties,propertyValues,namedFields,fieldValues);
      else if (fieldValues!=null && fieldValues.Length>0)
        cAttribBuilder = new CustomAttributeBuilder(con,ConstructorArgs,namedFields,fieldValues);
      else if (propertyValues!=null && propertyValues.Length>0)
        cAttribBuilder = new CustomAttributeBuilder(con,ConstructorArgs,namedProperties,propertyValues);
      else if (ConstructorArgs!=null)
        cAttribBuilder = new CustomAttributeBuilder((ConstructorInfo)con,ConstructorArgs);
      else 
        // KIRK: Add a support for a parameterless CustomAttribute constructor
        cAttribBuilder = new CustomAttributeBuilder((ConstructorInfo)con, new object[0]);

      return cAttribBuilder;
    }
  }

  internal class AssemblyLoader : MarshalByRefObject
  {
    public Assembly LoadAssemblyByPatialName(string assemblyName)
    {
      return Assembly.LoadWithPartialName(assemblyName);
    }
  }
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.