25using System.Collections.Generic;
26using System.Diagnostics;
35 internal readonly
struct CustomModifiers : IEquatable<CustomModifiers>, IEnumerable<CustomModifiers.Entry>
38 public readonly record
struct Entry(
Type Type, bool IsRequired);
58 void System.Collections.IEnumerator.Reset()
64 public Entry Current =>
new Entry(types[index], required);
68 if (types ==
null || index == types.Length)
73 if (index == types.Length)
91 object System.Collections.IEnumerator.Current =>
Current;
93 void IDisposable.Dispose()
102 readonly Type[] types;
108 internal CustomModifiers(List<CustomModifiersBuilder.Item> list)
112 var count = list.Count;
113 foreach (var item
in list)
115 if (item.required != required)
117 required = item.required;
122 types =
new Type[count];
125 foreach (var item
in list)
127 if (item.required != required)
129 required = item.required;
130 types[index++] = required ? MarkerType.ModReq :
MarkerType.ModOpt;
133 types[index++] = item.type;
141 CustomModifiers(
Type[] types)
143 Debug.Assert(types ==
null || types.Length != 0);
147 public Enumerator GetEnumerator()
149 return new Enumerator(types);
152 IEnumerator<Entry> IEnumerable<Entry>.GetEnumerator()
154 return GetEnumerator();
157 System.Collections.IEnumerator
System.Collections.IEnumerable.GetEnumerator()
159 return GetEnumerator();
164 get {
return types ==
null; }
167 public bool Equals(CustomModifiers other)
169 return Util.ArrayEquals(types, other.types);
172 public override bool Equals(
object obj)
174 var other = obj as CustomModifiers?;
175 return other !=
null && Equals(other.Value);
178 public override int GetHashCode()
180 return Util.GetHashCode(types);
183 public override string ToString()
188 var sb =
new StringBuilder();
190 foreach (var e
in this)
192 sb.Append(sep).Append(e.IsRequired ?
"modreq(" :
"modopt(").Append(e.Type.FullName).Append(
')');
196 return sb.ToString();
199 public bool ContainsMissingType
201 get {
return Type.ContainsMissingType(types); }
204 Type[] GetRequiredOrOptional(
bool required)
207 return Type.EmptyTypes;
210 foreach (var e
in this)
211 if (e.IsRequired == required)
214 var result =
new Type[count];
215 foreach (var e
in this)
216 if (e.IsRequired == required)
217 result[--count] = e.Type;
222 internal Type[] GetRequired()
224 return GetRequiredOrOptional(
true);
227 internal Type[] GetOptional()
229 return GetRequiredOrOptional(
false);
238 for (var i = 0; i < types.Length; i++)
243 var type = types[i].BindTypeParameters(binder);
244 if (!ReferenceEquals(type, types[i]))
247 result = (
Type[])types.Clone();
253 return new CustomModifiers(result);
258 var b = br.PeekByte();
259 if (!IsCustomModifier(b))
260 return new CustomModifiers();
262 var list =
new List<Type>();
266 var cmod = br.ReadByte() == Signature.ELEMENT_TYPE_CMOD_REQD ? MarkerType.ModReq :
MarkerType.ModOpt;
273 list.Add(
Signature.ReadTypeDefOrRefEncoded(module, br, context));
276 while (IsCustomModifier(b));
278 return new CustomModifiers(list.ToArray());
283 var b = br.PeekByte();
284 while (IsCustomModifier(b))
287 br.ReadCompressedUInt();
292 internal static CustomModifiers FromReqOpt(
Type[] req,
Type[] opt)
294 List<Type> list =
null;
296 if (opt !=
null && opt.Length != 0)
299 list =
new List<Type>(opt);
302 if (req !=
null && req.Length != 0)
304 list ??=
new List<Type>();
310 return new CustomModifiers();
312 return new CustomModifiers(list.ToArray());
315 static bool IsCustomModifier(
byte b)
317 return b == Signature.ELEMENT_TYPE_CMOD_OPT || b ==
Signature.ELEMENT_TYPE_CMOD_REQD;
320 internal static CustomModifiers Combine(CustomModifiers mods1, CustomModifiers mods2)
326 else if (mods2.IsEmpty)
332 var combo =
new Type[mods1.types.Length + mods2.types.Length];
333 Array.Copy(mods1.types, combo, mods1.types.Length);
334 Array.Copy(mods2.types, 0, combo, mods1.types.Length, mods2.types.Length);
335 return new CustomModifiers(combo);
IKVM.Reflection.Type Type
object System.Collections.IEnumerator. Current