The Labs \ Source Viewer \ SSCLI \ System.Reflection.Emit \ TypeNameBuilder

  1. // ==++==
  2. //
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. //
  14. // ==--==
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Runtime.CompilerServices;
  18. namespace System.Reflection.Emit
  19. {
  20.     // TypeNameBuilder is NOT thread safe NOR hardened for OOM NOR reliable
  21.     internal class TypeNameBuilder
  22.     {
  23.         internal enum Format
  24.         {
  25.             ToString,
  26.             FullName,
  27.             AssemblyQualifiedName
  28.         }
  29.        
  30.         #region FCalls
  31.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  32.         private static extern IntPtr _CreateTypeNameBuilder();
  33.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  34.         private static extern void _ReleaseTypeNameBuilder(IntPtr pAQN);
  35.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  36.         private static extern void _OpenGenericArguments(IntPtr tnb);
  37.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  38.         private static extern void _CloseGenericArguments(IntPtr tnb);
  39.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  40.         private static extern void _OpenGenericArgument(IntPtr tnb);
  41.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  42.         private static extern void _CloseGenericArgument(IntPtr tnb);
  43.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  44.         private static extern void _AddName(IntPtr tnb, string name);
  45.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  46.         private static extern void _AddPointer(IntPtr tnb);
  47.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  48.         private static extern void _AddByRef(IntPtr tnb);
  49.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  50.         private static extern void _AddSzArray(IntPtr tnb);
  51.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  52.         private static extern void _AddArray(IntPtr tnb, int rank);
  53.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  54.         private static extern void _AddAssemblySpec(IntPtr tnb, string assemblySpec);
  55.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  56.         private static extern string _ToString(IntPtr tnb);
  57.         [MethodImplAttribute(MethodImplOptions.InternalCall)]
  58.         private static extern void _Clear(IntPtr tnb);
  59.         #endregion
  60.        
  61.         #region Static Members
  62.        
  63.         // TypeNameBuilder is NOT thread safe NOR hardened for OOM NOR reliable
  64.         static internal string ToString(Type type, Format format)
  65.         {
  66.             if (format == Format.FullName || format == Format.AssemblyQualifiedName) {
  67.                 if (!type.IsGenericTypeDefinition && type.ContainsGenericParameters)
  68.                     return null;
  69.             }
  70.            
  71.             TypeNameBuilder tnb = new TypeNameBuilder(_CreateTypeNameBuilder());
  72.             tnb.Clear();
  73.             tnb.ConstructAssemblyQualifiedNameWorker(type, format);
  74.             string toString = tnb.ToString();
  75.             tnb.Dispose();
  76.             return toString;
  77.         }
  78.         #endregion
  79.        
  80.         #region Private Data Members
  81.         private IntPtr m_typeNameBuilder;
  82.         #endregion
  83.        
  84.         #region Constructor
  85.         private TypeNameBuilder(IntPtr typeNameBuilder)
  86.         {
  87.             m_typeNameBuilder = typeNameBuilder;
  88.         }
  89.         internal void Dispose()
  90.         {
  91.             _ReleaseTypeNameBuilder(m_typeNameBuilder);
  92.         }
  93.         #endregion
  94.        
  95.         #region private Members
  96.         private void AddElementType(Type elementType)
  97.         {
  98.             if (elementType.HasElementType)
  99.                 AddElementType(elementType.GetElementType());
  100.            
  101.             if (elementType.IsPointer)
  102.                 AddPointer();
  103.             else if (elementType.IsByRef)
  104.                 AddByRef();
  105.             else if (elementType.IsSzArray)
  106.                 AddSzArray();
  107.             else if (elementType.IsArray)
  108.                
  109.                
  110.                
  111.                 AddArray(elementType.GetArrayRank());
  112.         }
  113.        
  114.         private void ConstructAssemblyQualifiedNameWorker(Type type, Format format)
  115.         {
  116.             Type rootType = type;
  117.            
  118.             while (rootType.HasElementType)
  119.                 rootType = rootType.GetElementType();
  120.            
  121.             // Append namespace + nesting + name
  122.             List<Type> nestings = new List<Type>();
  123.             for (Type t = rootType; t != null; t = t.IsGenericParameter ? null : t.DeclaringType)
  124.                 nestings.Add(t);
  125.            
  126.             for (int i = nestings.Count - 1; i >= 0; i--) {
  127.                 Type enclosingType = nestings[i];
  128.                 string name = enclosingType.Name;
  129.                
  130.                 if (i == nestings.Count - 1 && enclosingType.Namespace != null && enclosingType.Namespace.Length != 0)
  131.                     name = enclosingType.Namespace + "." + name;
  132.                
  133.                 AddName(name);
  134.             }
  135.            
  136.             // Append generic arguments
  137.             if (rootType.IsGenericType && (!rootType.IsGenericTypeDefinition || format == Format.ToString)) {
  138.                 Type[] genericArguments = rootType.GetGenericArguments();
  139.                
  140.                 OpenGenericArguments();
  141.                 for (int i = 0; i < genericArguments.Length; i++) {
  142.                     Format genericArgumentsFormat = format == Format.FullName ? Format.AssemblyQualifiedName : format;
  143.                    
  144.                     OpenGenericArgument();
  145.                     ConstructAssemblyQualifiedNameWorker(genericArguments[i], genericArgumentsFormat);
  146.                     CloseGenericArgument();
  147.                 }
  148.                 CloseGenericArguments();
  149.             }
  150.            
  151.             // Append pointer, byRef and array qualifiers
  152.             AddElementType(type);
  153.            
  154.             if (format == Format.AssemblyQualifiedName)
  155.                 AddAssemblySpec(type.Module.Assembly.FullName);
  156.         }
  157.        
  158.         private void OpenGenericArguments()
  159.         {
  160.             _OpenGenericArguments(m_typeNameBuilder);
  161.         }
  162.         private void CloseGenericArguments()
  163.         {
  164.             _CloseGenericArguments(m_typeNameBuilder);
  165.         }
  166.         private void OpenGenericArgument()
  167.         {
  168.             _OpenGenericArgument(m_typeNameBuilder);
  169.         }
  170.         private void CloseGenericArgument()
  171.         {
  172.             _CloseGenericArgument(m_typeNameBuilder);
  173.         }
  174.         private void AddName(string name)
  175.         {
  176.             _AddName(m_typeNameBuilder, name);
  177.         }
  178.         private void AddPointer()
  179.         {
  180.             _AddPointer(m_typeNameBuilder);
  181.         }
  182.         private void AddByRef()
  183.         {
  184.             _AddByRef(m_typeNameBuilder);
  185.         }
  186.         private void AddSzArray()
  187.         {
  188.             _AddSzArray(m_typeNameBuilder);
  189.         }
  190.         private void AddArray(int rank)
  191.         {
  192.             _AddArray(m_typeNameBuilder, rank);
  193.         }
  194.         private void AddAssemblySpec(string assemblySpec)
  195.         {
  196.             _AddAssemblySpec(m_typeNameBuilder, assemblySpec);
  197.         }
  198.         public override string ToString()
  199.         {
  200.             return _ToString(m_typeNameBuilder);
  201.         }
  202.         private void Clear()
  203.         {
  204.             _Clear(m_typeNameBuilder);
  205.         }
  206.         #endregion
  207.     }
  208. }

Developer Fusion