Beispiel #1
0
        private static void PrettyName(StringBuilder sb, TypeSig typeSig, bool prettyBaseType)
        {
            if (typeSig == null)
            {
                return;
            }

            switch (typeSig.ElementType)
            {
            case ElementType.Class:
            case ElementType.ValueType:
                sb.Append(SigPrettyName(typeSig, prettyBaseType));
                return;

            case ElementType.Ptr:
                PrettyName(sb, typeSig.Next, prettyBaseType);
                sb.Append('*');
                return;

            case ElementType.ByRef:
                PrettyName(sb, typeSig.Next, prettyBaseType);
                sb.Append('&');
                return;

            case ElementType.SZArray:
                PrettyName(sb, typeSig.Next, prettyBaseType);
                sb.Append("[]");
                return;

            case ElementType.Pinned:
                PrettyName(sb, typeSig.Next, prettyBaseType);
                return;

            case ElementType.Array:
            {
                PrettyName(sb, typeSig.Next, prettyBaseType);
                ArraySig arraySig = (ArraySig)typeSig;
                sb.Append('[');
                uint rank = arraySig.Rank;
                if (rank == 0)
                {
                    throw new NotSupportedException();
                }
                else if (rank == 1)
                {
                    sb.Append('*');
                }
                else
                {
                    for (int i = 0; i < (int)rank; i++)
                    {
                        if (i != 0)
                        {
                            sb.Append(',');
                        }

                        const int  NO_LOWER = int.MinValue;
                        const uint NO_SIZE  = uint.MaxValue;
                        int        lower    = arraySig.LowerBounds.Get(i, NO_LOWER);
                        uint       size     = arraySig.Sizes.Get(i, NO_SIZE);
                        if (lower != NO_LOWER)
                        {
                            sb.Append(lower);
                            sb.Append("..");
                            if (size != NO_SIZE)
                            {
                                sb.Append(lower + (int)size - 1);
                            }
                            else
                            {
                                sb.Append('.');
                            }
                        }
                    }
                }
                sb.Append(']');
                return;
            }

            case ElementType.Var:
            case ElementType.MVar:
            {
                var gs = (GenericSig)typeSig;
                sb.Append(gs.IsMethodVar ? "!!" : "!");
                sb.Append(gs.Number);
                return;
            }

            case ElementType.GenericInst:
            {
                GenericInstSig genSig = (GenericInstSig)typeSig;
                sb.Append(SigPrettyName(genSig.GenericType, prettyBaseType));

                sb.Append('<');
                bool last = false;
                foreach (var arg in genSig.GenericArguments)
                {
                    if (last)
                    {
                        sb.Append(',');
                    }
                    last = true;
                    PrettyName(sb, arg, prettyBaseType);
                }
                sb.Append('>');
                return;
            }

            case ElementType.CModReqd:
            {
                PrettyName(sb, typeSig.Next, prettyBaseType);
                CModReqdSig modreq = (CModReqdSig)typeSig;
                sb.AppendFormat(" modreq({0})", modreq.Modifier.FullName);
                return;
            }

            case ElementType.CModOpt:
            {
                PrettyName(sb, typeSig.Next, prettyBaseType);
                CModOptSig modopt = (CModOptSig)typeSig;
                sb.AppendFormat(" modopt({0})", modopt.Modifier.FullName);
                return;
            }

            default:
                if (typeSig is CorLibTypeSig corTypeSig)
                {
                    sb.Append(SigPrettyName(corTypeSig, prettyBaseType));
                    return;
                }

                throw new ArgumentOutOfRangeException("PrettyName " + typeSig.GetType().Name);
            }
        }
Beispiel #2
0
        public TypeSig Duplicate(TypeSig typeSig)
        {
            if (!IsDuplicateNeeded(typeSig))
            {
                return(typeSig);
            }

            switch (typeSig.ElementType)
            {
            case ElementType.Class:
            case ElementType.ValueType:
                return(typeSig);

            case ElementType.Ptr:
                return(new PtrSig(Duplicate(typeSig.Next)));

            case ElementType.ByRef:
                return(new ByRefSig(Duplicate(typeSig.Next)));

            case ElementType.SZArray:
                return(new SZArraySig(Duplicate(typeSig.Next)));

            case ElementType.Pinned:
                return(new PinnedSig(Duplicate(typeSig.Next)));

            case ElementType.Array:
            {
                ArraySig arySig = (ArraySig)typeSig;
                return(new ArraySig(Duplicate(arySig.Next), arySig.Rank, Duplicate(arySig.Sizes), Duplicate(arySig.LowerBounds)));
            }

            case ElementType.Var:
            {
                GenericVar genVar = (GenericVar)typeSig;
                TypeSig    result = GenReplacer.Replace(genVar);
                if (result != null)
                {
                    return(result);
                }
                return(new GenericVar(genVar.Number, genVar.OwnerType));
            }

            case ElementType.MVar:
            {
                GenericMVar genMVar = (GenericMVar)typeSig;
                TypeSig     result  = GenReplacer.Replace(genMVar);
                if (result != null)
                {
                    return(result);
                }
                return(new GenericMVar(genMVar.Number, genMVar.OwnerMethod));
            }

            case ElementType.GenericInst:
            {
                GenericInstSig genSig = (GenericInstSig)typeSig;
                return(new GenericInstSig(genSig.GenericType, Duplicate(genSig.GenericArguments)));
            }

            case ElementType.CModReqd:
            {
                CModReqdSig modreq = (CModReqdSig)typeSig;
                return(new CModReqdSig(modreq.Modifier, Duplicate(modreq.Next)));
            }

            case ElementType.CModOpt:
            {
                CModOptSig modopt = (CModOptSig)typeSig;
                return(new CModOptSig(modopt.Modifier, Duplicate(modopt.Next)));
            }

            default:
                if (typeSig is CorLibTypeSig)
                {
                    return(typeSig);
                }

                throw new ArgumentOutOfRangeException("Duplicate TypeSig " + typeSig.GetType().Name);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Relocates the <see cref="TypeSig"/>.
        /// </summary>
        /// <param name="typeSig">The type sig.</param>
        /// <returns>A new type if it was relocated, null otherwise</returns>
        /// <exception cref="InvalidOperationException">If signature is of unknown type.</exception>
        public virtual TypeSig TryRelocateTypeSig(TypeSig typeSig)
        {
            if (typeSig == null)
            {
                return(null);
            }

            if (typeSig is CorLibTypeSig corLibTypeSig)
            {
                return(TryRelocateCorLibTypeSig(corLibTypeSig));
            }

            if (typeSig is GenericInstSig genericInstSig)
            {
                return(TryRelocateGeneric(genericInstSig));
            }

            //if (typeSig is PtrSig)
            //    return null;

            if (typeSig is ByRefSig byRefSig)
            {
                return(TryRelocateByRef(byRefSig));
            }

            if (typeSig is ArraySig arraySig)
            {
                return(TryRelocateArray(arraySig));
            }

            if (typeSig is SZArraySig szArraySig)
            {
                return(TryRelocateSZArray(szArraySig));
            }

            if (typeSig is GenericVar)
            {
                return(null); // TODO constraints
            }
            if (typeSig is GenericMVar)
            {
                return(null); // TODO constraints
            }
            if (typeSig is ClassOrValueTypeSig)
            {
                var typeRef      = typeSig.TryGetTypeRef();
                var typeDefOrRef = typeRef != null?TryRelocateTypeRef(typeRef) : TryRelocateTypeDefOrRef(typeSig.ToTypeDefOrRef());

                if (typeDefOrRef == null)
                {
                    return(null);
                }
                if (typeSig is ValueTypeSig)
                {
                    return(new ValueTypeSig(typeDefOrRef));
                }
                return(typeDefOrRef.ToTypeSig());
            }

            if (typeSig is CModOptSig cModOptSig)
            {
                var next     = TryRelocateTypeSig(cModOptSig.Next);
                var modifier = TryRelocateTypeDefOrRef(cModOptSig.Modifier);
                if (next == null && modifier == null)
                {
                    return(null);
                }
                return(new CModOptSig(modifier ?? cModOptSig.Modifier, next ?? cModOptSig.Next));
            }

            if (typeSig is CModReqdSig cModReqdSig)
            {
                var next     = TryRelocateTypeSig(cModReqdSig.Next);
                var modifier = TryRelocateTypeDefOrRef(cModReqdSig.Modifier);
                if (next == null && modifier == null)
                {
                    return(null);
                }
                return(new CModReqdSig(modifier ?? cModReqdSig.Modifier, next ?? cModReqdSig.Next));
            }

            if (typeSig is FnPtrSig)
            {
                return(null); // TODO
            }
            if (typeSig is PtrSig)
            {
                var next = TryRelocateTypeSig(typeSig.Next);
                return(next != null ? new PtrSig(next) : null);
            }

            if (typeSig is PinnedSig)
            {
                var next = TryRelocateTypeSig(typeSig.Next);
                return(next != null ? new PinnedSig(next) : null);
            }

            throw new InvalidOperationException($"type {typeSig.GetType()} not supported (MoFo)");
        }