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); } }
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); } }
/// <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)"); }