TypeSig ResolveGenericArgs(TypeSig typeSig) { if (!this.recursionCounter.Increment()) { return(null); } if (this.ReplaceGenericArg(ref typeSig)) { this.recursionCounter.Decrement(); return(typeSig); } TypeSig result; switch (typeSig.ElementType) { case ElementType.Ptr: result = new PtrSig(this.ResolveGenericArgs(typeSig.Next)); break; case ElementType.ByRef: result = new ByRefSig(this.ResolveGenericArgs(typeSig.Next)); break; case ElementType.Var: result = new GenericVar((typeSig as GenericVar).Number); break; case ElementType.ValueArray: result = new ValueArraySig(this.ResolveGenericArgs(typeSig.Next), (typeSig as ValueArraySig).Size); break; case ElementType.SZArray: result = new SZArraySig(this.ResolveGenericArgs(typeSig.Next)); break; case ElementType.MVar: result = new GenericMVar((typeSig as GenericMVar).Number); break; case ElementType.CModReqd: result = new CModReqdSig((typeSig as ModifierSig).Modifier, this.ResolveGenericArgs(typeSig.Next)); break; case ElementType.CModOpt: result = new CModOptSig((typeSig as ModifierSig).Modifier, this.ResolveGenericArgs(typeSig.Next)); break; case ElementType.Module: result = new ModuleSig((typeSig as ModuleSig).Index, this.ResolveGenericArgs(typeSig.Next)); break; case ElementType.Pinned: result = new PinnedSig(this.ResolveGenericArgs(typeSig.Next)); break; case ElementType.FnPtr: throw new NotSupportedException("FnPtr is not supported."); case ElementType.Array: var arraySig = (ArraySig)typeSig; var sizes = new List <uint>(arraySig.Sizes); var lbounds = new List <int>(arraySig.LowerBounds); result = new ArraySig(this.ResolveGenericArgs(typeSig.Next), arraySig.Rank, sizes, lbounds); break; case ElementType.GenericInst: var gis = (GenericInstSig)typeSig; var genArgs = new List <TypeSig>(gis.GenericArguments.Count); foreach (TypeSig ga in gis.GenericArguments) { genArgs.Add(this.ResolveGenericArgs(ga)); } result = new GenericInstSig(this.ResolveGenericArgs(gis.GenericType) as ClassOrValueTypeSig, genArgs); break; default: result = typeSig; break; } this.recursionCounter.Decrement(); return(result); }
TypeSig Create2(TypeSig type) { if (type == null) { return(type); } TypeSig result; GenericSig varSig; switch (type.ElementType) { case ElementType.Void: case ElementType.Boolean: case ElementType.Char: case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.String: case ElementType.TypedByRef: case ElementType.I: case ElementType.U: case ElementType.Object: result = type; break; case ElementType.Ptr: result = new PtrSig(Create2(type.Next)); break; case ElementType.ByRef: result = new ByRefSig(Create2(type.Next)); break; case ElementType.Array: var ary = (ArraySig)type; result = new ArraySig(ary.Next, ary.Rank, ary.Sizes, ary.LowerBounds); break; case ElementType.SZArray: result = new SZArraySig(Create2(type.Next)); break; case ElementType.Pinned: result = new PinnedSig(Create2(type.Next)); break; case ElementType.ValueType: case ElementType.Class: result = type; break; case ElementType.Var: varSig = (GenericSig)type; if (genericArgs != null && varSig.Number < (uint)genericArgs.Count) { result = genericArgs[(int)varSig.Number]; updated = true; } else { result = type; } break; case ElementType.MVar: varSig = (GenericSig)type; if (genericMethodArgs != null && varSig.Number < (uint)genericMethodArgs.Count) { result = genericMethodArgs[(int)varSig.Number]; updated = true; } else { result = type; } break; case ElementType.GenericInst: var gis = (GenericInstSig)type; var newGis = new GenericInstSig(Create2(gis.GenericType) as ClassOrValueTypeSig, gis.GenericArguments.Count); for (int i = 0; i < gis.GenericArguments.Count; i++) { newGis.GenericArguments.Add(Create2(gis.GenericArguments[i])); } result = newGis; break; case ElementType.ValueArray: result = new ValueArraySig(type.Next, ((ValueArraySig)type).Size); break; case ElementType.Module: result = new ModuleSig(((ModuleSig)type).Index, type.Next); break; case ElementType.CModReqd: result = new CModReqdSig(((ModifierSig)type).Modifier, type.Next); break; case ElementType.CModOpt: result = new CModOptSig(((ModifierSig)type).Modifier, type.Next); break; case ElementType.FnPtr: result = new FnPtrSig(Create(((FnPtrSig)type).MethodSig)); break; case ElementType.End: case ElementType.R: case ElementType.Sentinel: case ElementType.Internal: default: result = type; break; } return(result); }
/// <summary> /// Reads the next type /// </summary> /// <returns>A new <see cref="TypeSig"/> instance or <c>null</c> if invalid element type</returns> private TypeSig ReadType() { if (!recursionCounter.Increment()) { return(null); } uint num; TypeSig nextType, result = null; switch ((ElementType)reader.ReadByte()) { case ElementType.Void: result = corLibTypes.Void; break; case ElementType.Boolean: result = corLibTypes.Boolean; break; case ElementType.Char: result = corLibTypes.Char; break; case ElementType.I1: result = corLibTypes.SByte; break; case ElementType.U1: result = corLibTypes.Byte; break; case ElementType.I2: result = corLibTypes.Int16; break; case ElementType.U2: result = corLibTypes.UInt16; break; case ElementType.I4: result = corLibTypes.Int32; break; case ElementType.U4: result = corLibTypes.UInt32; break; case ElementType.I8: result = corLibTypes.Int64; break; case ElementType.U8: result = corLibTypes.UInt64; break; case ElementType.R4: result = corLibTypes.Single; break; case ElementType.R8: result = corLibTypes.Double; break; case ElementType.String: result = corLibTypes.String; break; case ElementType.TypedByRef: result = corLibTypes.TypedReference; break; case ElementType.I: result = corLibTypes.IntPtr; break; case ElementType.U: result = corLibTypes.UIntPtr; break; case ElementType.Object: result = corLibTypes.Object; break; case ElementType.Ptr: result = new PtrSig(ReadType()); break; case ElementType.ByRef: result = new ByRefSig(ReadType()); break; case ElementType.ValueType: result = new ValueTypeSig(ReadTypeDefOrRef()); break; case ElementType.Class: result = new ClassSig(ReadTypeDefOrRef()); break; case ElementType.FnPtr: result = new FnPtrSig(ReadSig()); break; case ElementType.SZArray: result = new SZArraySig(ReadType()); break; case ElementType.CModReqd: result = new CModReqdSig(ReadTypeDefOrRef(), ReadType()); break; case ElementType.CModOpt: result = new CModOptSig(ReadTypeDefOrRef(), ReadType()); break; case ElementType.Sentinel: result = new SentinelSig(); break; case ElementType.Pinned: result = new PinnedSig(ReadType()); break; case ElementType.Var: if (!reader.ReadCompressedUInt32(out num)) { break; } result = new GenericVar(num, gpContext.Type); break; case ElementType.MVar: if (!reader.ReadCompressedUInt32(out num)) { break; } result = new GenericMVar(num, gpContext.Method); break; case ElementType.ValueArray: nextType = ReadType(); if (!reader.ReadCompressedUInt32(out num)) { break; } result = new ValueArraySig(nextType, num); break; case ElementType.Module: if (!reader.ReadCompressedUInt32(out num)) { break; } result = new ModuleSig(num, ReadType()); break; case ElementType.GenericInst: nextType = ReadType(); if (!reader.ReadCompressedUInt32(out num)) { break; } var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num); var args = genericInstSig.GenericArguments; for (uint i = 0; i < num; i++) { args.Add(ReadType()); } result = genericInstSig; break; case ElementType.Array: nextType = ReadType(); uint rank; if (!reader.ReadCompressedUInt32(out rank)) { break; } if (rank == 0) { result = new ArraySig(nextType, rank); break; } if (!reader.ReadCompressedUInt32(out num)) { break; } var sizes = new List <uint>((int)num); for (uint i = 0; i < num; i++) { uint size; if (!reader.ReadCompressedUInt32(out size)) { goto exit; } sizes.Add(size); } if (!reader.ReadCompressedUInt32(out num)) { break; } var lowerBounds = new List <int>((int)num); for (uint i = 0; i < num; i++) { int size; if (!reader.ReadCompressedInt32(out size)) { goto exit; } lowerBounds.Add(size); } result = new ArraySig(nextType, rank, sizes, lowerBounds); break; case ElementType.Internal: IntPtr address; if (IntPtr.Size == 4) { address = new IntPtr(reader.ReadInt32()); } else { address = new IntPtr(reader.ReadInt64()); } result = helper.ConvertRTInternalAddress(address); break; case ElementType.End: case ElementType.R: default: result = null; break; } exit: recursionCounter.Decrement(); return(result); }
void AddArraySig() => TypeSig = new ArraySig(TypeSig, ArrayRank.Value, ArraySizes.Value, ArrayLowerBounds.Value);
void AddArraySig() { TypeSig = new ArraySig(TypeSig, arrayRank.Value, arraySizes.Value, arrayLowerBounds.Value); }
public static void TypeSigName(StringBuilder sb, TypeSig tySig, bool printGenOwner, int depth = 0) { if (depth > 512) { throw new TypeLoadException("The TypeSig chain is too long. Or there are some recursive generics that are expanded"); } if (tySig == null) { return; } switch (tySig.ElementType) { case ElementType.Class: case ElementType.ValueType: case ElementType.TypedByRef: ClassSigName(sb, tySig); return; case ElementType.Ptr: TypeSigName(sb, tySig.Next, printGenOwner, depth + 1); sb.Append('*'); return; case ElementType.ByRef: TypeSigName(sb, tySig.Next, printGenOwner, depth + 1); sb.Append('&'); return; case ElementType.Pinned: TypeSigName(sb, tySig.Next, printGenOwner, depth + 1); return; case ElementType.SZArray: TypeSigName(sb, tySig.Next, printGenOwner, depth + 1); sb.Append("[]"); return; case ElementType.Array: { TypeSigName(sb, tySig.Next, printGenOwner, depth + 1); ArraySig arySig = (ArraySig)tySig; GetArraySigPostfix(sb, arySig); return; } case ElementType.CModReqd: TypeSigName(sb, tySig.Next, printGenOwner, depth + 1); sb.Append(" modreq("); ClassSigName(sb, ((CModReqdSig)tySig).Modifier.ResolveTypeDef()); sb.Append(')'); return; case ElementType.CModOpt: TypeSigName(sb, tySig.Next, printGenOwner, depth + 1); sb.Append(" modopt("); ClassSigName(sb, ((CModOptSig)tySig).Modifier.ResolveTypeDef()); sb.Append(')'); return; case ElementType.GenericInst: { GenericInstSig genInstSig = (GenericInstSig)tySig; TypeSigName(sb, genInstSig.GenericType, printGenOwner, depth + 1); sb.Append('<'); TypeSigListName(sb, genInstSig.GenericArguments, printGenOwner); sb.Append('>'); return; } case ElementType.Var: case ElementType.MVar: { var genSig = (GenericSig)tySig; if (genSig.IsMethodVar) { sb.Append("!!"); } else { sb.Append('!'); if (printGenOwner) { sb.Append('('); ClassSigName(sb, genSig.OwnerType); sb.Append(')'); } } sb.Append(genSig.Number); return; } default: if (tySig is CorLibTypeSig) { ClassSigName(sb, tySig); return; } throw new ArgumentOutOfRangeException(); } }
private static TypeSig ReplaceGenericSigImpl(TypeSig tySig, IGenericReplacer replacer) { if (tySig == null) { return(null); } switch (tySig.ElementType) { case ElementType.Class: case ElementType.ValueType: case ElementType.TypedByRef: return(tySig); case ElementType.Ptr: return(new PtrSig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.ByRef: return(new ByRefSig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.Pinned: return(new PinnedSig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.SZArray: return(new SZArraySig(ReplaceGenericSigImpl(tySig.Next, replacer))); case ElementType.Array: { ArraySig arySig = (ArraySig)tySig; return(new ArraySig(ReplaceGenericSigImpl(arySig.Next, replacer), arySig.Rank, arySig.Sizes, arySig.LowerBounds)); } case ElementType.CModReqd: { CModReqdSig modreqdSig = (CModReqdSig)tySig; return(new CModReqdSig(modreqdSig.Modifier, ReplaceGenericSigImpl(modreqdSig.Next, replacer))); } case ElementType.CModOpt: { CModOptSig modoptSig = (CModOptSig)tySig; return(new CModOptSig(modoptSig.Modifier, ReplaceGenericSigImpl(modoptSig.Next, replacer))); } case ElementType.GenericInst: { GenericInstSig genInstSig = (GenericInstSig)tySig; return(new GenericInstSig(genInstSig.GenericType, ReplaceGenericSigListImpl(genInstSig.GenericArguments, replacer))); } case ElementType.Var: { GenericVar genVarSig = (GenericVar)tySig; TypeSig result = replacer.Replace(genVarSig); if (result != null) { return(result); } return(genVarSig); } case ElementType.MVar: { GenericMVar genMVarSig = (GenericMVar)tySig; TypeSig result = replacer.Replace(genMVarSig); if (result != null) { return(result); } return(genMVarSig); } default: if (tySig is CorLibTypeSig) { return(tySig); } throw new NotSupportedException(); } }