Example #1
0
        // Array and pointer types might cause deep recursions; visit them iteratively
        // rather than recursively.
        public override void Visit(IArrayTypeReference arrayTypeReference)
        {
            // We don't visit the current array type; it has already been visited.
            // We go straight to the element type and visit it.
            ITypeReference current = arrayTypeReference.GetElementType(Context);

            while (true)
            {
                bool mustVisitChildren = VisitTypeReference(current);
                if (!mustVisitChildren)
                {
                    return;
                }
                else if (current is IArrayTypeReference)
                {
                    // The element type is itself an array type, and we must visit *its* element type.
                    // Iterate rather than recursing.
                    current = ((IArrayTypeReference)current).GetElementType(Context);
                    continue;
                }
                else
                {
                    // The element type is not an array type and we must visit its children.
                    // Dispatch the type in order to visit its children.
                    DispatchAsReference(current);
                    return;
                }
            }
        }
Example #2
0
        /// <summary>
        /// Strip off *, &amp;, and [].
        /// </summary>
        private static ITypeReference UnwrapTypeReference(ITypeReference typeReference, EmitContext context)
        {
            while (true)
            {
                IArrayTypeReference arrType = typeReference as IArrayTypeReference;
                if (arrType != null)
                {
                    typeReference = arrType.GetElementType(context);
                    continue;
                }

                IPointerTypeReference pointer = typeReference as IPointerTypeReference;
                if (pointer != null)
                {
                    typeReference = pointer.GetTargetType(context);
                    continue;
                }

                IManagedPointerTypeReference reference = typeReference as IManagedPointerTypeReference;
                if (reference != null)
                {
                    typeReference = reference.GetTargetType(context);
                    continue;
                }

                return(typeReference);
            }
        }
Example #3
0
        private static void VisitTypeReference(ITypeReference typeReference, EmitContext context)
        {
            Debug.Assert(typeReference != null);

            IArrayTypeReference arrayType = typeReference as IArrayTypeReference;

            if (arrayType != null)
            {
                VisitTypeReference(arrayType.GetElementType(context), context);
                return;
            }

            IPointerTypeReference pointerType = typeReference as IPointerTypeReference;

            if (pointerType != null)
            {
                VisitTypeReference(pointerType.GetTargetType(context), context);
                return;
            }

            //IManagedPointerTypeReference managedPointerType = typeReference as IManagedPointerTypeReference;
            //if (managedPointerType != null)
            //{
            //    VisitTypeReference(managedPointerType.GetTargetType(this.context));
            //    return;
            //}

            IModifiedTypeReference modifiedType = typeReference as IModifiedTypeReference;

            if (modifiedType != null)
            {
                foreach (var custModifier in modifiedType.CustomModifiers)
                {
                    VisitTypeReference(custModifier.GetModifier(context), context);
                }
                VisitTypeReference(modifiedType.UnmodifiedType, context);
                return;
            }

            // Visit containing type
            INestedTypeReference nestedType = typeReference.AsNestedTypeReference;

            if (nestedType != null)
            {
                VisitTypeReference(nestedType.GetContainingType(context), context);
            }

            // Visit generic arguments
            IGenericTypeInstanceReference genericInstance = typeReference.AsGenericTypeInstanceReference;

            if (genericInstance != null)
            {
                foreach (var arg in genericInstance.GetGenericArguments(context))
                {
                    VisitTypeReference(arg, context);
                }
            }
        }
Example #4
0
        private static void AppendAssemblyQualifierIfNecessary(StringBuilder sb, ITypeReference typeReference, out bool isAssemQualified, EmitContext context)
        {
            INestedTypeReference nestedType = typeReference.AsNestedTypeReference;

            if (nestedType != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, nestedType.GetContainingType(context), out isAssemQualified, context);
                return;
            }

            IGenericTypeInstanceReference genInst = typeReference.AsGenericTypeInstanceReference;

            if (genInst != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, genInst.GetGenericType(context), out isAssemQualified, context);
                return;
            }

            IArrayTypeReference arrType = typeReference as IArrayTypeReference;

            if (arrType != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, arrType.GetElementType(context), out isAssemQualified, context);
                return;
            }

            IPointerTypeReference pointer = typeReference as IPointerTypeReference;

            if (pointer != null)
            {
                AppendAssemblyQualifierIfNecessary(sb, pointer.GetTargetType(context), out isAssemQualified, context);
                return;
            }

            isAssemQualified = false;
            IAssemblyReference      referencedAssembly = null;
            INamespaceTypeReference namespaceType      = typeReference.AsNamespaceTypeReference;

            if (namespaceType != null)
            {
                referencedAssembly = namespaceType.GetUnit(context) as IAssemblyReference;
            }

            if (referencedAssembly != null)
            {
                var containingAssembly = context.Module.GetContainingAssembly(context);

                if (containingAssembly == null || !ReferenceEquals(referencedAssembly, containingAssembly))
                {
                    sb.Append(", ");
                    sb.Append(MetadataWriter.StrongName(referencedAssembly));
                    isAssemQualified = true;
                }
            }
        }
Example #5
0
 public virtual void Visit(IArrayTypeReference arrayTypeReference)
 {
     this.Visit(arrayTypeReference.GetElementType(Context));
 }
Example #6
0
 // Array and pointer types might cause deep recursions; visit them iteratively
 // rather than recursively.
 public override void Visit(IArrayTypeReference arrayTypeReference)
 {
     // We don't visit the current array type; it has already been visited.
     // We go straight to the element type and visit it.
     ITypeReference current = arrayTypeReference.GetElementType(Context);
     while (true)
     {
         bool mustVisitChildren = VisitTypeReference(current);
         if (!mustVisitChildren)
         {
             return;
         }
         else if (current is IArrayTypeReference)
         {
             // The element type is itself an array type, and we must visit *its* element type.
             // Iterate rather than recursing.
             current = ((IArrayTypeReference)current).GetElementType(Context);
             continue;
         }
         else
         {
             // The element type is not an array type and we must visit its children.
             // Dispatch the type in order to visit its children.
             DispatchAsReference(current);
             return;
         }
     }
 }
Example #7
0
        internal static string GetSerializedTypeName(this ITypeReference typeReference, EmitContext context, ref bool isAssemblyQualified)
        {
            var                 pooled  = PooledStringBuilder.GetInstance();
            StringBuilder       sb      = pooled.Builder;
            IArrayTypeReference arrType = typeReference as IArrayTypeReference;

            if (arrType != null)
            {
                typeReference = arrType.GetElementType(context);
                bool isAssemQual = false;
                AppendSerializedTypeName(sb, typeReference, ref isAssemQual, context);
                if (arrType.IsSZArray)
                {
                    sb.Append("[]");
                }
                else
                {
                    sb.Append('[');
                    if (arrType.Rank == 1)
                    {
                        sb.Append('*');
                    }

                    sb.Append(',', (int)arrType.Rank - 1);

                    sb.Append(']');
                }

                goto done;
            }

            IPointerTypeReference pointer = typeReference as IPointerTypeReference;

            if (pointer != null)
            {
                typeReference = pointer.GetTargetType(context);
                bool isAssemQual = false;
                AppendSerializedTypeName(sb, typeReference, ref isAssemQual, context);
                sb.Append('*');
                goto done;
            }

            INamespaceTypeReference namespaceType = typeReference.AsNamespaceTypeReference;

            if (namespaceType != null)
            {
                var name = namespaceType.NamespaceName;
                if (name.Length != 0)
                {
                    sb.Append(name);
                    sb.Append('.');
                }

                sb.Append(GetMangledAndEscapedName(namespaceType));
                goto done;
            }


            if (typeReference.IsTypeSpecification())
            {
                ITypeReference uninstantiatedTypeReference = typeReference.GetUninstantiatedGenericType(context);

                ArrayBuilder <ITypeReference> consolidatedTypeArguments = ArrayBuilder <ITypeReference> .GetInstance();

                typeReference.GetConsolidatedTypeArguments(consolidatedTypeArguments, context);

                bool uninstantiatedTypeIsAssemblyQualified = false;
                sb.Append(GetSerializedTypeName(uninstantiatedTypeReference, context, ref uninstantiatedTypeIsAssemblyQualified));
                sb.Append('[');
                bool first = true;
                foreach (ITypeReference argument in consolidatedTypeArguments)
                {
                    if (first)
                    {
                        first = false;
                    }
                    else
                    {
                        sb.Append(',');
                    }

                    bool isAssemQual = true;
                    AppendSerializedTypeName(sb, argument, ref isAssemQual, context);
                }
                consolidatedTypeArguments.Free();

                sb.Append(']');
                goto done;
            }

            INestedTypeReference nestedType = typeReference.AsNestedTypeReference;

            if (nestedType != null)
            {
                bool nestedTypeIsAssemblyQualified = false;
                sb.Append(GetSerializedTypeName(nestedType.GetContainingType(context), context, ref nestedTypeIsAssemblyQualified));
                sb.Append('+');
                sb.Append(GetMangledAndEscapedName(nestedType));
                goto done;
            }

            // TODO: error
done:
            if (isAssemblyQualified)
            {
                AppendAssemblyQualifierIfNecessary(sb, UnwrapTypeReference(typeReference, context), out isAssemblyQualified, context);
            }

            return(pooled.ToStringAndFree());
        }
Example #8
0
 public virtual void Visit(IArrayTypeReference arrayTypeReference)
 {
     this.Visit(arrayTypeReference.GetElementType(Context));
 }
Example #9
0
 public override ITypeReference GetType(EmitContext context)
 => _arrayType.GetElementType(context);