Module.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 » Module.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.  
*/
using System;
using System.Reflection;
using System.Collections;
using Rail.Transformation;

namespace Rail.Reflect{
  /// <summary>
  /// 
  /// </summary>
  public abstract class RModule : CustomAttributeOwner
  {
    #region fields
    /// <summary>
    /// 
    /// </summary>
    protected RAssembly assembly;
    /// <summary>
    /// 
    /// </summary>
    protected string name;
    /// <summary>
    /// 
    /// </summary>
    protected string fileName;
    /// <summary>
    /// 
    /// </summary>
    protected ArrayList rTypes;
    /// <summary>
    /// The table of the module global methods
    /// </summary>
    protected Hashtable globalMethods;

    #endregion

    #region Information access
    public RMethodBase [] GlobalMethods
    {
      get
      {
        RMethodBase [] arrayToReturn = new RMethodBase[0];
        if (this.globalMethods!=null)
        {
          arrayToReturn = new RMethodBase[this.globalMethods.Count];
          int i = 0;
          foreach (RMethodBase rmb in this.globalMethods)
          {
            arrayToReturn[i] = rmb;
          }
        }
        return arrayToReturn;
      }
    }

    /// <summary>
    /// 
    /// </summary>
    internal ArrayList RTypes
    {
      get
      {
        return this.rTypes;
      }
    }
    /// <summary>
    /// Gets the parent assembly.
    /// </summary>
    public virtual RAssembly Assembly 
    {
      get 
      {
        return this.assembly;
      }
    }

    /// <summary>
    /// Gets the name of the module. This is also the filename
    /// where this module will be saved. If the assembly has only one
    /// module, this name must match the filename where the assembly is
    /// saved.
    /// </summary>
    public virtual String Name 
    {
      get 
      {
        return this.name;
      }
      set 
      {
        throw new NotSupportedException();
      }
    }

    /// <summary>
    /// Gets the name of the module, including the pathname.
    /// </summary>
    public virtual String FullyQualifiedName 
    {
      get 
      {
        //TODO: What is the FullyQualifiedName of the Module?
        return this.fileName;
      }
    }
    /// <summary>
    /// Gets or sets the filename of the module, if it is a RModuleDef, probably this
    /// will be the same file as the RAssemblyDef
    /// </summary>
    public virtual String FileName 
    {
      get
      {
        return this.fileName;
      }
      set
      {
        throw new NotSupportedException();
      }
    
    }
    #endregion

    /// <summary>
    /// Get a Global Method definition
    /// </summary>
    /// <param name="name">The name of the method</param>
    /// <param name="parameterTypesFullNames">the full names of the types of the parameters of the types correctly ordered</param>
    /// <returns>The fetch global method</returns>
    public RMethodBase GetGlobalMethod(string name, string [] parameterTypesFullNames)
    {
      if (this.globalMethods==null)
      {
        this.globalMethods = new Hashtable();
        return null;
      }
      System.Text.StringBuilder sb = new System.Text.StringBuilder(name);
      if (parameterTypesFullNames!=null && parameterTypesFullNames.Length>0)
        foreach (string s in parameterTypesFullNames)
          sb.Append(s);
      return (RMethodBase)this.globalMethods[sb.ToString()];
    }
    #region Type management
    /// <summary>
    /// Returns a specific type from this <code>Module</code>.
    /// </summary>
    /// <remarks>
    /// This method can be used to retrieve array types based on primitive
    /// types that contained in this <code>Module</code>. The
    /// notation for specifying array types is the same as the one that can
    /// be used with the CLR methods <code>Type.GetType()</code> and 
    /// <code>Assembly.GetType()</code>.
    /// </remarks>
    /// <param name="name">The name of the type</param>
    /// <returns>The requested type or null if it is not found</returns>
    public virtual RType GetType(String name) 
    {
      if (this.rTypes==null) return null;
      if (this.rTypes.Count==0) return null;
      IEnumerator ienum = this.rTypes.GetEnumerator();
      RType rt = null;
      bool found = false;
      while (ienum.MoveNext())
      {
        rt = (RType)ienum.Current;
        if (rt.FullName.Equals(name) || rt.NameWithNameSpace.Equals(name))
        {
          found = true;
          break;
        }
      }
      if (found)
        return rt;
      return null;
    }

    /// <summary>
    /// Returns an array with all the types defined in this 
    /// <code>Module</code>.
    /// </summary>
    /// <returns></returns>
    public virtual RType[] GetTypes() 
    { 
      if (this.rTypes==null) return new RType[0];
      if (this.rTypes.Count==0) return new RType[0];
      IEnumerator ienum = this.rTypes.GetEnumerator();
      RType [] rt = new RType[this.rTypes.Count];
      int i = 0;
      while (ienum.MoveNext())
      {
        rt[i] = (RType)ienum.Current;
        i++;
      }
      return rt;
    }
    #endregion
  }

  /// <summary>
  /// 
  /// </summary>
  public sealed class RModuleRef : RModule 
  {
    /// <summary>
    /// 
    /// </summary>
    /// <param name="assembly"></param>
    /// <param name="mod"></param>
    internal RModuleRef(RAssemblyDef assembly,Module mod) 
    {
      this.assembly = assembly;
      this.fileName = mod.FullyQualifiedName;
      this.name = mod.Name;
      Type [] tps = mod.GetTypes();
      this.rTypes = new ArrayList();
      if (tps!=null)
      {
        for (int i = 0; i < tps.Length;i++)
                    this.rTypes.Add(assembly.GetRTypeRef(tps[i]));
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="assembly"></param>
    /// <param name="mod"></param>
    internal RModuleRef(RAssembly assembly,RModuleRef mod) 
    {
      this.assembly = assembly;
      this.fileName = mod.FileName;
      this.name = mod.Name;
      RType [] rt = mod.GetTypes();
      this.rTypes = new ArrayList();
      if (rt!=null)
      {
        for (int i = 0; i < rt.Length;i++)
          this.rTypes.Add((RTypeRef)rt[i]);
      }
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="assembly"></param>
    /// <param name="name"></param>
    /// <param name="fileName"></param>
    internal RModuleRef(RAssembly assembly, String name, String fileName) 
    {
      this.assembly = assembly;
      this.name = name;
      this.fileName = fileName;
      this.rTypes = new ArrayList();
    }
  }

  /// <summary>  
  /// - A module is always associated with an assembly.
  /// - It's not permitted to change the assembly associated with a module.
  /// - Support constructors to create a new module based on a old one
  /// 
  /// </summary>
  public sealed class RModuleDef : RModule, ICustomAttributeOwnerDef, IVisitable 
  {
    /// <summary>
    /// Creates a new module. The module is created empty.
    /// </summary>
    /// <param name="assembly">The assembly where this module belongs.</param>
    /// <param name="name">The name of the module.</param>
    /// <param name="fileName">The file name of the module.</param>
    internal RModuleDef(RAssembly assembly, String name, String fileName) 
    {
      this.assembly = assembly;
      this.name = name;
      this.fileName = fileName;
      this.rTypes = new ArrayList();
    }

    /// <summary>
    /// Creates a new module, copying all the contents 
    /// from the given module
    /// </summary>    
    /// <param name="assembly">The assembly where this module will be created.</param>
    /// <param name="original">The RModuleDef used to define this one.</param>
    internal RModuleDef(RAssembly assembly, RModuleDef original) 
    {
      this.assembly = assembly;
      this.name = original.Name;
      this.fileName = original.FileName;
      RType [] rt = original.GetTypes();
      this.rTypes = new ArrayList();
      if (rt!=null)
      {
        for (int i = 0; i < rt.Length;i++)
          this.rTypes.Add((RTypeDef)rt[i]);
      }
    }

    #region Information access    
    /// <summary>
    /// Gets or sets the name of the module. This is also the filename
    /// where this module will be saved. If the assembly has only one
    /// module, this name must match the filename where the assembly is
    /// saved.
    /// </summary>
    public override String Name 
    {
      set 
      {
        this.name = value;
      }
    }

    /// <summary>
    /// Gets or sets the filename of the module, if it is a RModuleDef, probably this
    /// will be the same file as the RAssemblyDef
    /// </summary>
    public override String FileName 
    {
      set
      {
        this.fileName = value;
      }
    
    }
    #endregion

    #region Custom Attributes
    /// <summary>
    /// 
    /// </summary>
    /// <param name="attribute"></param>
    public void AddCustomAttributtes(RCustomAttrib attribute) 
    {
      InternalAddCustomAttributtes(attribute);
    }

    /// <summary>
    /// TODO: How should the attribute be specified?
    /// </summary>
    /// <param name="attribute"></param>
    public void RemoveCustomAttribute(RCustomAttrib attribute) 
    {
      InternalRemoveCustomAttribute(attribute);
    }

    #endregion

    #region Type management
    /// <summary>
    /// Returns a specific type from this <code>Module</code>.
    /// </summary>
    /// <remarks>
    /// This method can be used to retrieve array types based on primitive
    /// types that contained in this <code>Module</code>. The
    /// notation for specifying array types is the same as the one that can
    /// be used with the CLR methods <code>Type.GetType()</code> and 
    /// <code>Assembly.GetType()</code>.
    /// </remarks>
    /// <param name="name">The name of the type</param>
    /// <returns>The requested type or null if it is not found</returns>
    public override RType GetType(String name) 
    {
      if (this.rTypes==null) return null;
      if (this.rTypes.Count==0) return null;
      RTypeDef rt = null;
      bool found = false;
      for (int i=0;i<this.rTypes.Count;i++)
      {
        rt = (RTypeDef)this.rTypes[i];
        if (rt.NameWithNameSpace.Equals(name) || rt.FullName.Equals(name))
        {
          found = true;
          break;
        }
      }
      if (found)
        return rt;
      return null;
    }

    /// <summary>
    /// Returns an array with all the types defined in this 
    /// <code>Module</code>.
    /// </summary>
    /// <returns></returns>
    public override RType[] GetTypes() 
    { 
      if (this.rTypes==null) return new RTypeDef[0];
      if (this.rTypes.Count==0) return new RTypeDef[0];
      IEnumerator ienum = this.rTypes.GetEnumerator();
      RTypeDef [] rt = new RTypeDef[this.rTypes.Count];
      int i = 0;
      while (ienum.MoveNext())
      {
        rt[i] = (RTypeDef)ienum.Current;
        i++;
      }
      return rt;
    }
    /// <summary>
    /// Creates a new type in this assembly.
    /// </summary>
    /// <param name="name">The name of the type. Must be unique inside
    /// the assembly that contains this module.</param>
    /// <returns></returns>
    public RTypeDef DefineType(String name, String nameSpace) 
    {
      RTypeDef rtd = new RTypeDef(name);
      if (nameSpace!=null)
        rtd.NameSpace = nameSpace;
      rtd.Module = this;
      rtd.Assembly = this.assembly;
      if (this.rTypes==null)
        this.rTypes = new ArrayList();
      this.rTypes.Add(rtd);
      return rtd;
    }

    /// <summary>
    /// Adds a Global Method to the module
    /// </summary>
    /// <param name="rMethod">The method to add</param>
    /// <returns>The method added</returns>
    public RMethodBase DefineGlobalMethod(RMethodBase rMethod)
    {
      if (this.globalMethods==null)
        this.globalMethods = new Hashtable();
      System.Text.StringBuilder sb = new System.Text.StringBuilder(rMethod.Name);
      if (rMethod.ParametersCount>0)
        foreach (RParameter rp in rMethod.GetParameters())
          sb.Append(rp.ParameterType.NameWithNameSpace);
      rMethod.GlobalSetModule = this;
      this.globalMethods.Add(sb.ToString(),rMethod);
      return (RMethodBase)this.globalMethods[sb.ToString()];
    }

    /// <summary>
    /// Define a new global method.
    /// To define a global constructor set the name .cctor and the returnType=NULL
    /// </summary>
    /// <param name="name">The name of the method</param>
    /// <param name="returnType">The return type (NULL if is a constructor)</param>
    /// <param name="parameters">The array of RParameters</param>
    /// <param name="attributes">The method attributes </param>
    /// <returns>The created global method</returns>
    public RMethodBase DefineGlobalMethod(string name, RReturnType returnType, RParameter [] parameters, MethodAttributes attributes)
    {
      if (returnType==null && (name.Equals(".ctor") || name.Equals(".cctor")))
      {
        RConstructorDef rc = new RConstructorDef();
        if (parameters!=null && parameters.Length>0)
          foreach (RParameter r in parameters)
            rc.AddParameter(r);
        rc.Attributes = attributes;
        rc.GlobalSetModule = this;
        return rc;
      }
      else
      {
        RMethodDef rm = new RMethodDef();
        rm.Name = name;
        rm.ReturnType = returnType;
        if (parameters!=null && parameters.Length>0)
          foreach (RParameter r in parameters)
            rm.AddParameter(r);
        rm.Attributes = attributes;
        rm.GlobalSetModule = this;
        return rm;
      }
    }

    /// <summary>
    /// Remove a global methos definition from the module
    /// </summary>
    /// <param name="methodName">The name of the method</param>
    /// <param name="methodParameters">the parameters of the method</param>
    /// <returns></returns>
    public RMethodBase RemoveGlobalMethod(string methodName, RParameter [] methodParameters)
    {
      RMethodBase rm = null;
      if (this.globalMethods==null)
      {
        this.globalMethods = new Hashtable();
        return null;
      }
      System.Text.StringBuilder sb = new System.Text.StringBuilder(methodName);
      if (methodParameters!=null && methodParameters.Length>0)
        foreach (RParameter rp in methodParameters)
          sb.Append(rp.ParameterType.NameWithNameSpace);
      if (this.globalMethods.Contains(sb.ToString()))
      {
        rm = (RMethodBase)this.globalMethods[sb.ToString()];
        this.globalMethods.Remove(sb.ToString());
      }
      return rm;
    }

    /// <summary>
    /// Remove a global method definiton from the module
    /// </summary>
    /// <param name="rm">The method to remove</param>
    /// <returns>The removed method</returns>
    public RMethodBase RemoveGlobalMethod(RMethodBase rm)
    {
      if (rm!=null)
        return RemoveGlobalMethod(rm.Name,rm.GetParameters());
      return null;
    }


    /// <summary>
    /// 
    /// </summary>
    /// <param name="original"></param>
    /// <returns></returns>
    internal RType GetRType(RType original)
    {
      if (original==null)
        return null;
      RType rtr;
      if (original is RTypeDef)
      {
        rtr = ((RAssemblyDef)this.assembly).GetType(original.NameWithNameSpace);
        if (rtr==null)
        {
          rtr = new RTypeRef(original.Name,original.NameSpace,(RAssemblyDef)this.assembly);
          ((RAssemblyDef)this.assembly).AddTypeRef((RTypeRef)rtr);
          ((RTypeRef)rtr).SetAttributes(original.Attributes);
          ((RTypeRef)rtr).SetBaseType(GetRType(original.BaseType));
          ((RTypeRef)rtr).SetDeclaringType(GetRType(original.DeclaringType));
          ((RTypeRef)rtr).SetAssembly(original.Assembly);
          if (original.IsArray)
          {
            ((RTypeRef)rtr).SetElementType(GetRType(original.ElementType));
            ARRAY.ArrayShape arrayShape = new ARRAY.ArrayShape(); 
            arrayShape.LoBounds = original.RArrayShape.LoBounds;
            arrayShape.NumLoBounds = original.RArrayShape.NumLoBounds;
            arrayShape.NumSizes = original.RArrayShape.NumSizes;
            arrayShape.Rank = original.RArrayShape.Rank;
            arrayShape.Sizes = original.RArrayShape.Sizes;
            ((RTypeRef)rtr).SetRArrayShape(arrayShape);
          }
        }
      }
      else
      {
        rtr = ((RAssemblyDef)this.assembly).GetType(original.NameWithNameSpace);
        if (rtr==null)
        {
          rtr = ((RAssemblyDef)this.assembly).RModuleDef.GetType(original.NameWithNameSpace);
          if (rtr == null)
          {
            rtr = new RTypeRef(original.Name,original.NameSpace,(RAssemblyDef)this.assembly);
            ((RAssemblyDef)this.assembly).AddTypeRef((RTypeRef)rtr);
            ((RTypeRef)rtr).SetAttributes(original.Attributes);
            ((RTypeRef)rtr).SetBaseType(GetRType(original.BaseType));
            ((RTypeRef)rtr).SetDeclaringType(GetRType(original.DeclaringType));
            ((RTypeRef)rtr).SetAssembly(original.Assembly);
            if (original.IsArray)
            {
              ((RTypeRef)rtr).SetElementType(GetRType(original.ElementType));
              ARRAY.ArrayShape arrayShape = new ARRAY.ArrayShape(); 
              arrayShape.LoBounds = original.RArrayShape.LoBounds;
              arrayShape.NumLoBounds = original.RArrayShape.NumLoBounds;
              arrayShape.NumSizes = original.RArrayShape.NumSizes;
              arrayShape.Rank = original.RArrayShape.Rank;
              arrayShape.Sizes = original.RArrayShape.Sizes;
              ((RTypeRef)rtr).SetRArrayShape(arrayShape);
            }
          }
        }
      }
      return rtr;
    }

    /// <summary>
    /// 
    /// </summary>
    /// <param name="iType"></param>
    /// <returns></returns>
    internal RType GetCorrectRType(RType iType)
    {
      RType rT =  
        ((RAssemblyDef)this.Assembly).RModuleDef.GetType(iType.NameWithNameSpace);
      if (rT==null)
      {
        if (((RAssemblyDef)this.Assembly).GetReferencedAssembly(iType.Assembly.Name.FullName)==null)
          ((RAssemblyDef)this.Assembly).AddReferencedAssembly(iType.Assembly.Name.FullName);
        rT =
          ((RAssemblyDef)this.Assembly).GetRTypeRef(iType.NameWithNameSpace);            
      }
      return rT;
    }
    
    /// <summary>
    /// Creates a new type in this assembly, using a given type 
    /// as template. The new type is a copy of the given, except that
    /// it is part of this assembly object.
    /// </summary>
    /// <param name="original">The type to be used as template.</param>
    /// <param name="newName">The name of the new type.</param>
    /// <returns></returns>
    public RTypeDef CopyType(RType original, String newName) 
    {
      string [] tokens = newName.Split('.');
      RTypeDef rtd = new RTypeDef(tokens[tokens.Length-1]);
      int tI = 0;
      while (tI < tokens.Length - 1)
      {
        if (tI!=0)
          rtd.NameSpace += ".";
        rtd.NameSpace = rtd.NameSpace + tokens[tI];
        tI++;
      }
      rtd.Assembly = this.assembly;
      rtd.Module = this;
      rtd.Attributes = original.Attributes;
      //TODO: Check if this BaseType is correct for copy of types?
      //Probably it needs also to be copyed to this module!!!
      //rtd.BaseType = GetRType(original.BaseType);
      if (null != rtd.BaseType)
        rtd.BaseType = GetCorrectRType(original.BaseType);

      rtd.BindingFlags = original.BindingFlags;
      //TODO: the same thing as in BaseType
      if (original.DeclaringType!=null)
        //rtd.DeclaringType = GetRType(original.DeclaringType);
        rtd.DeclaringType = GetCorrectRType(original.DeclaringType);
      if (original.IsArray)
      {
        //rtd.ElementType = GetRType(original.ElementType);
        rtd.ElementType = GetCorrectRType(original.ElementType);
        rtd.RArrayShape = new ARRAY.ArrayShape(); 
        rtd.RArrayShape.LoBounds = original.RArrayShape.LoBounds;
        rtd.RArrayShape.NumLoBounds = original.RArrayShape.NumLoBounds;
        rtd.RArrayShape.NumSizes = original.RArrayShape.NumSizes;
        rtd.RArrayShape.Rank = original.RArrayShape.Rank;
        rtd.RArrayShape.Sizes = original.RArrayShape.Sizes;
      }
      rtd.MemberType = MemberTypes.TypeInfo;

      RType [] inter = original.GetInterfaces();
      if (inter!=null)
        for (int i=0; i< inter.Length;i++)
        {
          rtd.AddInterface(GetCorrectRType(inter[i]));
        }

      RField [] fiel = original.GetFields();
      if (fiel!=null)
        for (int i=0;i<fiel.Length;i++)
          rtd.CopyField((RFieldDef)fiel[i],fiel[i].Name);
      this.rTypes.Add(rtd);


      RMethod [] meth = original.GetMethods();
      if (meth!=null)
        for (int i=0;i<meth.Length;i++)
          rtd.CopyMethod((RMethodDef)meth[i],meth[i].Name);

      RConstructor [] cons = original.GetConstructors();
      if (cons!=null)
        for (int i=0;i<cons.Length;i++)
          rtd.CopyConstructor((RConstructorDef)cons[i]);

      RProperty [] props = original.GetProperties();
      if (props!=null)
        for (int i=0;i<props.Length;i++)
          rtd.CopyProperty((RPropertyDef)props[i],props[i].Name);

      REvent [] even = original.GetEvents();
      if (even!=null)
        for (int i=0;i<even.Length;i++)
          rtd.CopyEvent((REventDef)even[i],even[i].Name);

      RMethod [] methTarget = rtd.GetMethods();
      if (meth!=null &&
        methTarget != null)
        if (meth.Length == methTarget.Length)
          for (int i=0;i<meth.Length;i++)
          {
            if (null != ((RMethodDef)meth[i]).MethodBody)
              rtd.CopyMethodBody((RMethodDef)meth[i],(RMethodDef)methTarget[i]);
          }
        else
          throw new InvalidProgramException();

      RConstructor [] consTarget = rtd.GetConstructors();
      if (cons!=null &&
        consTarget!=null)
        if (cons.Length == consTarget.Length)
          for (int i=0;i<cons.Length;i++)
          {
            if (null != ((RConstructorDef)cons[i]).MethodBody)
              rtd.CopyMethodBody((RConstructorDef)cons[i],(RConstructorDef)consTarget[i]);
          }
        else
          throw new InvalidProgramException();      
      
      AddCustomAttribsTo(rtd,original);
      return rtd;
    }


    internal void AddCustomAttribsTo(RMember target,RMember original)
    {
      RCustomAttrib [] cAttribs = original.GetCustomAttributes(false);
      foreach (RCustomAttrib r in cAttribs)
      {
        RParameter [] rcParamz = new RParameter[r.AttributeConstructor.ParametersCount];
        int i = 0;
        foreach (RParameter p in r.AttributeConstructor.GetParameters())
        {
          rcParamz[i] = new RParameter(i+1,(int)p.Attributes,p.Name,GetCorrectRType(p.ParameterType));
        }
        RType rcType = GetCorrectRType(r.AttributeConstructor.DeclaringType);
        RConstructor rc = rcType.GetConstructor( rcParamz);
        RCustomAttrib newAttrib = 
          new RCustomAttrib(rc,r.AttributeData,(RAssemblyDef)this.assembly);
        newAttrib.SetAttributeConstructorArguments(r.GetAttributeConstructorArguments());
        //TODO: add Fields and properties
        if (target is RFieldDef)
          ((RFieldDef)target).AddCustomAttributtes(newAttrib);
        else if (target is RPropertyDef)
          ((RPropertyDef)target).AddCustomAttributtes(newAttrib);
        else if (target is REventDef)
          ((REventDef)target).AddCustomAttributtes(newAttrib);
        else if (target is RMethodDef)
          ((RMethodDef)target).AddCustomAttributtes(newAttrib);
        else if (target is RConstructorDef)
          ((RConstructorDef)target).AddCustomAttributtes(newAttrib);
        else if (target is RTypeDef)
          ((RTypeDef)target).AddCustomAttributtes(newAttrib);
        else
          throw new InvalidProgramException();
      }
    }

    internal void AddCustomAttribsTo(RParameter target,RParameter original)
    {
      RCustomAttrib [] cAttribs = original.GetCustomAttributes(false);
      foreach (RCustomAttrib r in cAttribs)
      {
        RParameter [] rcParamz = new RParameter[r.AttributeConstructor.ParametersCount];
        int i = 0;
        foreach (RParameter p in r.AttributeConstructor.GetParameters())
        {
          rcParamz[i] = new RParameter(i+1,(int)p.Attributes,p.Name,GetCorrectRType(p.ParameterType));
        }
        RType rcType = GetCorrectRType(r.AttributeConstructor.DeclaringType);
        RConstructor rc = rcType.GetConstructor(rcParamz);
        RCustomAttrib newAttrib = 
          new RCustomAttrib(rc,r.AttributeData,(RAssemblyDef)this.assembly);
        newAttrib.SetAttributeConstructorArguments(r.GetAttributeConstructorArguments());
        //TODO: add Fields and properties
        target.AddCustomAttributtes(newAttrib);
      }
    }
    /// <summary>
    /// Removes a type from this module.
    /// </summary>
    /// <param name="typeName">The name of the type to be removed</param>
    public void RemoveType(String typeName) 
    {
      if (this.rTypes!=null)
        if (this.rTypes.Count>0)
        {
          IEnumerator ienum = this.rTypes.GetEnumerator();
          int i = 0;
          bool found = false;
          RTypeDef rtd = null;
          while (ienum.MoveNext())
          {
            rtd = (RTypeDef)ienum.Current;
            if (rtd.NameWithNameSpace.Equals(typeName))
            {
              found = true;
              break;
            }
            i++;
          }
          if (found)
            this.rTypes.RemoveAt(i);
        }
    }    


    /// <summary>
    /// To get a RTypeDef from it's token value in other metadata tables
    /// </summary>
    /// <param name="pos">The index in the table of the type given by the token</param>
    /// <returns></returns>
    internal RTypeDef GetTypeByToken(int pos)
    {
      
      if (this.rTypes==null) return null;
      if (this.rTypes.Count<=pos-2) 
        throw new IndexOutOfRangeException("Index out of bounds");
      return (RTypeDef)this.rTypes[pos-2];
    }

    /// <summary>
    /// To get a RTypeDef from the list by it's position
    /// </summary>
    /// <param name="pos">The index for the RTypeDef list (starts at 0)</param>
    /// <returns></returns>
    internal RTypeDef GetTypeAt(int pos)
    {
      if (this.rTypes==null) return null;
      if (this.rTypes.Count<=pos) 
        throw new IndexOutOfRangeException("Index out of bounds");
      return (RTypeDef)this.rTypes[pos];
    }
    #endregion

    /// <summary>
    /// Visits this module.
    /// </summary>
    /// <remarks>
    /// Visits the module itself and the types contained in it. The order by 
    /// which these elements are visited, depends on what is set in the Visitor.
    /// </remarks>
    /// <param name="v">The visitor to be used.</param>
    public void Accept(Visitor v) 
    {
      v.GetWalker().WalkModule(this);
    }
  }
}
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.