GenericArgumentContext.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. using dnlib.DotNet;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace HybridCLR.Editor.Meta
  8. {
  9. public class GenericArgumentContext
  10. {
  11. private readonly List<TypeSig> typeArgsStack;
  12. private readonly List<TypeSig> methodArgsStack;
  13. public GenericArgumentContext(List<TypeSig> typeArgsStack, List<TypeSig> methodArgsStack)
  14. {
  15. this.typeArgsStack = typeArgsStack;
  16. this.methodArgsStack = methodArgsStack;
  17. }
  18. public TypeSig Resolve(TypeSig typeSig)
  19. {
  20. if (!typeSig.ContainsGenericParameter)
  21. {
  22. return typeSig;
  23. }
  24. typeSig = typeSig.RemovePinnedAndModifiers();
  25. switch (typeSig.ElementType)
  26. {
  27. case ElementType.Ptr: return new PtrSig(Resolve(typeSig.Next));
  28. case ElementType.ByRef: return new ByRefSig(Resolve(typeSig.Next));
  29. case ElementType.SZArray: return new SZArraySig(Resolve(typeSig.Next));
  30. case ElementType.Array:
  31. {
  32. var ara = (ArraySig)typeSig;
  33. return new ArraySig(Resolve(typeSig.Next), ara.Rank, ara.Sizes, ara.LowerBounds);
  34. }
  35. case ElementType.Var:
  36. {
  37. GenericVar genericVar = (GenericVar)typeSig;
  38. var newSig = Resolve(typeArgsStack, genericVar.Number);
  39. if (newSig == null)
  40. {
  41. throw new Exception();
  42. }
  43. return newSig;
  44. }
  45. case ElementType.MVar:
  46. {
  47. GenericMVar genericVar = (GenericMVar)typeSig;
  48. var newSig = Resolve(methodArgsStack, genericVar.Number);
  49. if (newSig == null)
  50. {
  51. throw new Exception();
  52. }
  53. return newSig;
  54. }
  55. case ElementType.GenericInst:
  56. {
  57. var gia = (GenericInstSig)typeSig;
  58. return new GenericInstSig(gia.GenericType, gia.GenericArguments.Select(ga => Resolve(ga)).ToList());
  59. }
  60. case ElementType.FnPtr:
  61. {
  62. var fptr = (FnPtrSig)typeSig;
  63. var cs = fptr.Signature;
  64. CallingConventionSig ccs;
  65. switch (cs)
  66. {
  67. case MethodSig ms:
  68. {
  69. ccs = new MethodSig(ms.GetCallingConvention(), ms.GenParamCount, Resolve(ms.RetType), ms.Params.Select(p => Resolve(p)).ToList());
  70. break;
  71. }
  72. case PropertySig ps:
  73. {
  74. ccs = new PropertySig(ps.HasThis, Resolve(ps.RetType));
  75. break;
  76. }
  77. case GenericInstMethodSig gims:
  78. {
  79. ccs = new GenericInstMethodSig(gims.GenericArguments.Select(ga => Resolve(ga)).ToArray());
  80. break;
  81. }
  82. default: throw new NotSupportedException(cs.ToString());
  83. }
  84. return new FnPtrSig(ccs);
  85. }
  86. case ElementType.ValueArray:
  87. {
  88. var vas = (ValueArraySig)typeSig;
  89. return new ValueArraySig(Resolve(vas.Next), vas.Size);
  90. }
  91. default: return typeSig;
  92. }
  93. }
  94. private TypeSig Resolve(List<TypeSig> args, uint number)
  95. {
  96. return args[(int)number];
  97. }
  98. }
  99. }