public static Type GetTypeFromName(string name) { ClrTypeSpec spec = Parse(name); if (spec == null) { return(null); } return(spec.Resolve( assyName => Assembly.Load(assyName), //(assy, typeName) => assy == null ? RT.classForName(typeName) : assy.GetType(typeName)); <--- this goes into an infinite loop on a non-existent typename (assy, typeName) => assy == null ? (name.Equals(typeName) ? null : RT.classForName(typeName)) : assy.GetType(typeName))); }
static ClrTypeSpec Parse(string name) { int pos = 0; ClrTypeSpec spec = Parse(name, ref pos, false, false); if (spec == null) { return(null); // bad parse } if (pos < name.Length) { return(null); // ArgumentException ("Count not parse the whole type name", "typeName"); } return(spec); }
static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAssyQualName) { int pos = p; int name_start; bool hasModifiers = false; ClrTypeSpec spec = new ClrTypeSpec(); SkipSpace(name, ref pos); name_start = pos; for (; pos < name.Length; ++pos) { switch (name[pos]) { case '+': spec.AddName(name.Substring(name_start, pos - name_start)); name_start = pos + 1; break; case ',': case ']': spec.AddName(name.Substring(name_start, pos - name_start)); name_start = pos + 1; if (isRecursive && !allowAssyQualName) { p = pos; return spec; } hasModifiers = true; break; case '&': case '*': case '[': if (name[pos] != '[' && isRecursive) return null; // ArgumentException ("Generic argument can't be byref or pointer type", "typeName"); spec.AddName(name.Substring(name_start, pos - name_start)); name_start = pos + 1; hasModifiers = true; break; } if (hasModifiers) break; } if (name_start < pos) spec.AddName(name.Substring(name_start, pos - name_start)); if (hasModifiers) { for (; pos < name.Length; ++pos) { switch (name[pos]) { case '&': if (spec._isByRef) return null; // ArgumentException ("Can't have a byref of a byref", "typeName") spec._isByRef = true; break; case '*': if (spec._isByRef) return null; // ArgumentException ("Can't have a pointer to a byref type", "typeName"); ++spec._pointerLevel; break; case ',': if (isRecursive) { int end = pos; while (end < name.Length && name[end] != ']') ++end; if (end >= name.Length) return null; // ArgumentException ("Unmatched ']' while parsing generic argument assembly name"); spec._assemblyName = name.Substring(pos + 1, end - pos - 1).Trim(); p = end + 1; return spec; } spec._assemblyName = name.Substring(pos + 1).Trim(); pos = name.Length; break; case '[': if (spec._isByRef) return null; // ArgumentException ("Byref qualifier must be the last one of a type", "typeName"); ++pos; if (pos >= name.Length) return null; // ArgumentException ("Invalid array/generic spec", "typeName"); SkipSpace(name, ref pos); if (name[pos] != ',' && name[pos] != '*' && name[pos] != ']') {//generic args List<ClrTypeSpec> args = new List<ClrTypeSpec>(); if (spec.IsArray) return null; // ArgumentException ("generic args after array spec", "typeName"); while (pos < name.Length) { SkipSpace(name, ref pos); bool aqn = name[pos] == '['; if (aqn) ++pos; //skip '[' to the start of the type { ClrTypeSpec arg = Parse(name, ref pos, true, aqn); if (arg == null) return null; // bad generic arg args.Add(arg); } if (pos >= name.Length) return null; // ArgumentException ("Invalid generic arguments spec", "typeName"); if (name[pos] == ']') break; if (name[pos] == ',') ++pos; // skip ',' to the start of the next arg else return null; // ArgumentException ("Invalid generic arguments separator " + name [pos], "typeName") } if (pos >= name.Length || name[pos] != ']') return null; // ArgumentException ("Error parsing generic params spec", "typeName"); spec._genericParams = args; } else { //array spec int dimensions = 1; bool bound = false; while (pos < name.Length && name[pos] != ']') { if (name[pos] == '*') { if (bound) return null; // ArgumentException ("Array spec cannot have 2 bound dimensions", "typeName"); bound = true; } else if (name[pos] != ',') return null; // ArgumentException ("Invalid character in array spec " + name [pos], "typeName"); else ++dimensions; ++pos; SkipSpace(name, ref pos); } if (name[pos] != ']') return null; // ArgumentException ("Error parsing array spec", "typeName"); if (dimensions > 1 && bound) return null; // ArgumentException ("Invalid array spec, multi-dimensional array cannot be bound", "typeName") spec.AddArray(new ClrArraySpec(dimensions, bound)); } break; case ']': if (isRecursive) { p = pos + 1; return spec; } return null; // ArgumentException ("Unmatched ']'", "typeName"); default: return null; // ArgumentException ("Bad type def, can't handle '" + name [pos]+"'" + " at " + pos, "typeName"); } } } p = pos; return spec; }
static ClrTypeSpec Parse(string name, ref int p, bool isRecursive, bool allowAssyQualName) { int pos = p; int name_start; bool hasModifiers = false; ClrTypeSpec spec = new ClrTypeSpec(); SkipSpace(name, ref pos); name_start = pos; for (; pos < name.Length; ++pos) { switch (name[pos]) { case '+': spec.AddName(name.Substring(name_start, pos - name_start)); name_start = pos + 1; break; case ',': case ']': spec.AddName(name.Substring(name_start, pos - name_start)); name_start = pos + 1; if (isRecursive && !allowAssyQualName) { p = pos; return(spec); } hasModifiers = true; break; case '&': case '*': case '[': if (name[pos] != '[' && isRecursive) { return(null); // ArgumentException ("Generic argument can't be byref or pointer type", "typeName"); } spec.AddName(name.Substring(name_start, pos - name_start)); name_start = pos + 1; hasModifiers = true; break; } if (hasModifiers) { break; } } if (name_start < pos) { spec.AddName(name.Substring(name_start, pos - name_start)); } if (hasModifiers) { for (; pos < name.Length; ++pos) { switch (name[pos]) { case '&': if (spec._isByRef) { return(null); // ArgumentException ("Can't have a byref of a byref", "typeName") } spec._isByRef = true; break; case '*': if (spec._isByRef) { return(null); // ArgumentException ("Can't have a pointer to a byref type", "typeName"); } ++spec._pointerLevel; break; case ',': if (isRecursive) { int end = pos; while (end < name.Length && name[end] != ']') { ++end; } if (end >= name.Length) { return(null); // ArgumentException ("Unmatched ']' while parsing generic argument assembly name"); } spec._assemblyName = name.Substring(pos + 1, end - pos - 1).Trim(); p = end + 1; return(spec); } spec._assemblyName = name.Substring(pos + 1).Trim(); pos = name.Length; break; case '[': if (spec._isByRef) { return(null); // ArgumentException ("Byref qualifier must be the last one of a type", "typeName"); } ++pos; if (pos >= name.Length) { return(null); // ArgumentException ("Invalid array/generic spec", "typeName"); } SkipSpace(name, ref pos); if (name[pos] != ',' && name[pos] != '*' && name[pos] != ']') { //generic args List <ClrTypeSpec> args = new List <ClrTypeSpec>(); if (spec.IsArray) { return(null); // ArgumentException ("generic args after array spec", "typeName"); } while (pos < name.Length) { SkipSpace(name, ref pos); bool aqn = name[pos] == '['; if (aqn) { ++pos; //skip '[' to the start of the type } { ClrTypeSpec arg = Parse(name, ref pos, true, aqn); if (arg == null) { return(null); // bad generic arg } args.Add(arg); } if (pos >= name.Length) { return(null); // ArgumentException ("Invalid generic arguments spec", "typeName"); } if (name[pos] == ']') { break; } if (name[pos] == ',') { ++pos; // skip ',' to the start of the next arg } else { return(null); // ArgumentException ("Invalid generic arguments separator " + name [pos], "typeName") } } if (pos >= name.Length || name[pos] != ']') { return(null); // ArgumentException ("Error parsing generic params spec", "typeName"); } spec._genericParams = args; } else { //array spec int dimensions = 1; bool bound = false; while (pos < name.Length && name[pos] != ']') { if (name[pos] == '*') { if (bound) { return(null); // ArgumentException ("Array spec cannot have 2 bound dimensions", "typeName"); } bound = true; } else if (name[pos] != ',') { return(null); // ArgumentException ("Invalid character in array spec " + name [pos], "typeName"); } else { ++dimensions; } ++pos; SkipSpace(name, ref pos); } if (name[pos] != ']') { return(null); // ArgumentException ("Error parsing array spec", "typeName"); } if (dimensions > 1 && bound) { return(null); // ArgumentException ("Invalid array spec, multi-dimensional array cannot be bound", "typeName") } spec.AddArray(new ClrArraySpec(dimensions, bound)); } break; case ']': if (isRecursive) { p = pos + 1; return(spec); } return(null); // ArgumentException ("Unmatched ']'", "typeName"); default: return(null); // ArgumentException ("Bad type def, can't handle '" + name [pos]+"'" + " at " + pos, "typeName"); } } } p = pos; return(spec); }