45 internal static string Escape(
string name)
50 StringBuilder sb =
null;
51 for (
int pos = 0; pos <
name.Length; pos++)
63 sb ??=
new StringBuilder(
name, 0, pos,
name.Length + 3);
64 sb.Append(
"\\").Append(c);
72 return sb !=
null ? sb.ToString() :
name;
75 internal static string Unescape(
string name)
77 int pos =
name.IndexOf(
'\\');
81 var sb =
new StringBuilder(
name, 0, pos,
name.Length - 1);
82 for (; pos <
name.Length; pos++)
94 internal static TypeNameParser Parse(
string typeName,
bool throwOnError)
98 var parser =
new Parser(typeName);
105 var parser =
new Parser(typeName);
108 catch (ArgumentException)
117 var genericParameter = parser.pos != 0;
118 name = parser.NextNamePart();
130 if (withAssemblyName)
134 internal readonly
bool Error =>
name ==
null;
136 internal readonly
string FirstNamePart =>
name;
140 private struct Parser
143 readonly
string typeName;
150 internal Parser(
string typeName)
152 this.typeName = typeName;
156 void Check(
bool condition)
159 throw new ArgumentException(
"Invalid type name '" + typeName +
"'");
164 Check(pos < typeName.Length && typeName[pos++] == c);
167 bool TryConsume(
char c)
169 if (pos < typeName.Length && typeName[pos] == c)
180 internal string NextNamePart()
185 for (; pos < typeName.Length; pos++)
187 var c = typeName[pos];
191 Check(pos < typeName.Length &&
SpecialChars.IndexOf(typeName[pos]) != -1);
199 Check(pos - start != 0);
200 if (start == 0 && pos == typeName.Length)
203 return typeName.Substring(start, pos - start);
206 internal void ParseNested(
ref string[]
nested)
208 while (TryConsume(
'+'))
219 if (TryConsume(
']') || TryConsume(
'*') || TryConsume(
','))
241 while (TryConsume(
','));
250 while (pos < typeName.Length)
252 switch (typeName[pos])
275 internal void ParseAssemblyName(
bool genericParameter,
ref string assemblyName)
277 if (pos < typeName.Length)
279 if (typeName[pos] ==
']' && genericParameter)
288 if (genericParameter)
291 while (pos < typeName.Length)
293 char c = typeName[pos];
298 Check(pos < typeName.Length && typeName[pos++] ==
']');
309 Check(pos < typeName.Length && typeName[pos] ==
']');
310 assemblyName = typeName.Substring(start, pos - start).Replace(
"\\]",
"]");
322 Check(!genericParameter);
329 Check(pos < typeName.Length);
331 var c = typeName[pos];
345 while (TryConsume(
','))
347 Check(rank <
short.MaxValue);
356 void SkipWhiteSpace()
358 while (pos < typeName.Length && Char.IsWhiteSpace(typeName[pos]))
362 static void Add<T>(
ref T[] array, T elem)
366 array =
new T[] { elem };
370 Array.Resize(
ref array, array.Length + 1);
371 array[array.Length - 1] = elem;
375 internal Type GetType(Universe universe,
Module context,
bool throwOnError,
string originalName,
bool resolve,
bool ignoreCase)
377 Debug.Assert(!resolve || !ignoreCase);
378 var
name = TypeName.Split(this.name);
390 type =
asm.ResolveType(context,
name);
394 type =
asm.FindTypeIgnoreCase(
name.ToLowerInvariant());
398 type =
asm.FindType(
name);
401 else if (context ==
null)
405 type = universe.CoreLib.ResolveType(context,
name);
409 type = universe.CoreLib.FindTypeIgnoreCase(
name.ToLowerInvariant());
413 type = universe.CoreLib.FindType(
name);
421 type = context.FindTypeIgnoreCase(
name);
425 type = context.FindType(
name);
427 if (type ==
null && context != universe.CoreLib.ManifestModule)
431 type = universe.CoreLib.FindTypeIgnoreCase(
name);
435 type = universe.CoreLib.FindType(
name);
438 if (type ==
null && resolve)
440 if (universe.CoreLib.__IsMissing && !context.__IsMissing)
442 type = universe.CoreLib.ResolveType(context,
name);
446 type = context.Assembly.ResolveType(context,
name);
451 return Expand(type, context, throwOnError, originalName, resolve, ignoreCase);
454 internal Type Expand(
Type type,
Module context,
bool throwOnError,
string originalName,
bool resolve,
bool ignoreCase)
456 Debug.Assert(!resolve || !ignoreCase);
461 throw new TypeLoadException(originalName);
469 foreach (
string nest
in nested)
473 type = ignoreCase ? outer.FindNestedTypeIgnoreCase(
name.ToLowerInvariant()) : outer.FindNestedType(
name);
477 type = outer.Module.Universe.GetMissingTypeOrThrow(context, outer.Module, outer,
name);
478 else if (throwOnError)
479 throw new TypeLoadException(originalName);
489 for (
int i = 0; i < typeArgs.Length; i++)
491 typeArgs[i] =
genericParameters[i].GetType(type.Assembly.Universe, context, throwOnError, originalName, resolve, ignoreCase);
492 if (typeArgs[i] ==
null)
496 type = type.MakeGenericType(typeArgs);
503 type = modifier
switch
505 SZARRAY => type.MakeArrayType(),
506 BYREF => type.MakeByRefType(),
507 POINTER => type.MakePointerType(),
508 _ => type.MakeArrayType(modifier),