From d7848c305e3b311be32effeeb1a23f7d25875219 Mon Sep 17 00:00:00 2001 From: jfrijters Date: Thu, 20 Jan 2011 05:38:11 +0000 Subject: [PATCH] More type name fixes. This time to support the fact that the CLR and Mono both treat TypeNamespace and TypeName as separate names and do not consider fullName to be relevant. --- reflect/Assembly.cs | 30 +++++++--- reflect/Emit/AssemblyBuilder.cs | 54 +++++++++++++----- reflect/Emit/ModuleBuilder.cs | 15 +++-- reflect/Emit/TypeBuilder.cs | 4 +- reflect/Missing.cs | 32 +++++------ reflect/Module.cs | 13 ++++- reflect/Reader/AssemblyReader.cs | 6 +- reflect/Reader/GenericTypeParameter.cs | 2 +- reflect/Reader/ModuleReader.cs | 58 ++++++++++--------- reflect/Reader/ResourceModule.cs | 2 +- reflect/Reader/TypeDefImpl.cs | 7 ++- reflect/Type.cs | 26 ++------- reflect/TypeNameParser.cs | 77 +++++++++++++++++++++++++- reflect/Universe.cs | 6 +- 14 files changed, 224 insertions(+), 108 deletions(-) diff --git a/reflect/Assembly.cs b/reflect/Assembly.cs index 3bb527ec..9ba213e6 100644 --- a/reflect/Assembly.cs +++ b/reflect/Assembly.cs @@ -50,15 +50,29 @@ namespace IKVM.Reflection public abstract ManifestResourceInfo GetManifestResourceInfo(string resourceName); public abstract System.IO.Stream GetManifestResourceStream(string resourceName); - internal abstract Type GetTypeImpl(string typeName); - - // The differences between ResolveType and GetTypeImpl are: - // - ResolveType is only used when a type is assumed to exist (because another module's metadata claim it) - // - ResolveType takes the unescaped namespace and name parts as they exist in the metadata - // - ResolveType is overridden in MissingAssembly to return a MissingType - internal virtual Type ResolveType(string ns, string name) + internal Type GetTypeImpl(string typeName) { - return GetTypeImpl(TypeNameParser.Escape(ns == null ? name : ns + "." + name)); + Type type = FindType(TypeName.Split(TypeNameParser.Unescape(typeName))); + if (type == null && __IsMissing) + { + throw new MissingAssemblyException((MissingAssembly)this); + } + return type; + } + + internal abstract Type FindType(TypeName name); + + // The differences between ResolveType and FindType are: + // - ResolveType is only used when a type is assumed to exist (because another module's metadata claims it) + // - ResolveType can return a MissingType + internal Type ResolveType(TypeName typeName) + { + return FindType(typeName) ?? GetMissingType(typeName); + } + + internal virtual Type GetMissingType(TypeName name) + { + return null; } public Module[] GetModules() diff --git a/reflect/Emit/AssemblyBuilder.cs b/reflect/Emit/AssemblyBuilder.cs index e63cd596..633f09df 100644 --- a/reflect/Emit/AssemblyBuilder.cs +++ b/reflect/Emit/AssemblyBuilder.cs @@ -64,7 +64,7 @@ namespace IKVM.Reflection.Emit private readonly List customAttributes = new List(); private readonly List declarativeSecurity = new List(); private readonly List typeForwarders = new List(); - private Dictionary missingTypes; + private Dictionary missingTypes; private struct ResourceFile { @@ -73,6 +73,34 @@ namespace IKVM.Reflection.Emit internal ResourceAttributes Attributes; } + private struct ScopedTypeName : IEquatable + { + private readonly Type declaringType; + private readonly TypeName name; + + internal ScopedTypeName(Type declaringType, TypeName name) + { + this.declaringType = declaringType; + this.name = name; + } + + public override bool Equals(object obj) + { + ScopedTypeName? other = obj as ScopedTypeName?; + return other != null && ((IEquatable)other.Value).Equals(this); + } + + public override int GetHashCode() + { + return declaringType == null ? name.GetHashCode() : declaringType.GetHashCode() * 7 + name.GetHashCode(); + } + + bool IEquatable.Equals(ScopedTypeName other) + { + return other.declaringType == declaringType && other.name == name; + } + } + internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) : base(universe) { @@ -508,11 +536,11 @@ namespace IKVM.Reflection.Emit return list.ToArray(); } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { foreach (ModuleBuilder mb in modules) { - Type type = mb.GetTypeImpl(typeName); + Type type = mb.FindType(typeName); if (type != null) { return type; @@ -520,7 +548,7 @@ namespace IKVM.Reflection.Emit } foreach (Module module in addedModules) { - Type type = module.GetTypeImpl(typeName); + Type type = module.FindType(typeName); if (type != null) { return type; @@ -529,23 +557,23 @@ namespace IKVM.Reflection.Emit return null; } - internal override Type ResolveType(string ns, string name) + internal override Type GetMissingType(TypeName name) { - return base.ResolveType(ns, name) ?? GetMissingType(this.ManifestModule, null, ns, name); + return GetMissingType(this.ManifestModule, null, name); } - internal Type GetMissingType(Module module, Type declaringType, string ns, string name) + internal Type GetMissingType(Module module, Type declaringType, TypeName name) { if (missingTypes == null) { return null; } - Type mt = new MissingType(module, declaringType, ns, name); + ScopedTypeName stn = new ScopedTypeName(declaringType, name); Type type; - if (!missingTypes.TryGetValue(mt.FullName, out type)) + if (!missingTypes.TryGetValue(stn, out type)) { - missingTypes.Add(mt.FullName, mt); - type = mt; + type = new MissingType(module, declaringType, name.Namespace, name.Name); + missingTypes.Add(stn, type); } return type; } @@ -554,7 +582,7 @@ namespace IKVM.Reflection.Emit { if (missingTypes == null) { - missingTypes = new Dictionary(); + missingTypes = new Dictionary(); } } @@ -692,7 +720,7 @@ namespace IKVM.Reflection.Emit get { return assembly; } } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { return null; } diff --git a/reflect/Emit/ModuleBuilder.cs b/reflect/Emit/ModuleBuilder.cs index ada466b3..5623f196 100644 --- a/reflect/Emit/ModuleBuilder.cs +++ b/reflect/Emit/ModuleBuilder.cs @@ -48,7 +48,6 @@ namespace IKVM.Reflection.Emit private readonly List types = new List(); private readonly Dictionary typeTokens = new Dictionary(); private readonly Dictionary memberRefTypeTokens = new Dictionary(); - private readonly Dictionary fullNameToType = new Dictionary(); internal readonly ByteBuffer methodBodies = new ByteBuffer(128 * 1024); internal readonly List tokenFixupOffsets = new List(); internal readonly ByteBuffer initializedData = new ByteBuffer(512); @@ -227,7 +226,6 @@ namespace IKVM.Reflection.Emit { TypeBuilder typeBuilder = new TypeBuilder(owner, ns, name, attr); types.Add(typeBuilder); - fullNameToType.Add(typeBuilder.FullName, typeBuilder); return typeBuilder; } @@ -433,11 +431,16 @@ namespace IKVM.Reflection.Emit get { return asm; } } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName name) { - TypeBuilder type; - fullNameToType.TryGetValue(typeName, out type); - return type; + foreach (Type type in types) + { + if (type.__Namespace == name.Namespace && type.__Name == name.Name) + { + return type; + } + } + return null; } internal override void GetTypesImpl(List list) diff --git a/reflect/Emit/TypeBuilder.cs b/reflect/Emit/TypeBuilder.cs index 28ab084d..584f10bc 100644 --- a/reflect/Emit/TypeBuilder.cs +++ b/reflect/Emit/TypeBuilder.cs @@ -1038,9 +1038,9 @@ namespace IKVM.Reflection.Emit get { return token == 0x02000001; } } - internal override Type ResolveNestedType(string ns, string name) + internal override Type ResolveNestedType(TypeName typeName) { - return base.ResolveNestedType(ns, name) ?? ((AssemblyBuilder)ModuleBuilder.Assembly).GetMissingType(this.Module, this, ns, name); + return base.ResolveNestedType(typeName) ?? ((AssemblyBuilder)ModuleBuilder.Assembly).GetMissingType(this.Module, this, typeName); } } diff --git a/reflect/Missing.cs b/reflect/Missing.cs index 7b3b4257..f8117905 100644 --- a/reflect/Missing.cs +++ b/reflect/Missing.cs @@ -98,7 +98,7 @@ namespace IKVM.Reflection sealed class MissingAssembly : Assembly { - private readonly Dictionary types = new Dictionary(); + private readonly Dictionary types = new Dictionary(); private readonly MissingModule module; private readonly string name; @@ -109,14 +109,13 @@ namespace IKVM.Reflection this.name = name; } - internal override Type ResolveType(string ns, string name) + internal override Type GetMissingType(TypeName name) { - string fullName = ns == null ? name : ns + "." + name; Type type; - if (!types.TryGetValue(fullName, out type)) + if (!types.TryGetValue(name, out type)) { - type = new MissingType(module, null, ns, name); - types.Add(fullName, type); + type = new MissingType(module, null, name.Namespace, name.Name); + types.Add(name, type); } return type; } @@ -196,9 +195,9 @@ namespace IKVM.Reflection get { return true; } } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { - throw new MissingAssemblyException(this); + return null; } internal override IList GetCustomAttributesData(Type attributeType) @@ -277,9 +276,9 @@ namespace IKVM.Reflection get { throw new MissingModuleException(this); } } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { - throw new MissingModuleException(this); + return null; } internal override void GetTypesImpl(System.Collections.Generic.List list) @@ -354,7 +353,7 @@ namespace IKVM.Reflection private readonly Type declaringType; private readonly string ns; private readonly string name; - private Dictionary types; + private Dictionary types; internal MissingType(Module module, Type declaringType, string ns, string name) { @@ -364,18 +363,17 @@ namespace IKVM.Reflection this.name = name; } - internal override Type ResolveNestedType(string ns, string name) + internal override Type ResolveNestedType(TypeName typeName) { if (types == null) { - types = new Dictionary(); + types = new Dictionary(); } - string fullName = ns == null ? name : ns + "." + name; Type type; - if (!types.TryGetValue(fullName, out type)) + if (!types.TryGetValue(typeName, out type)) { - type = new MissingType(module, this, ns, name); - types.Add(fullName, type); + type = new MissingType(module, this, typeName.Namespace, typeName.Name); + types.Add(typeName, type); } return type; } diff --git a/reflect/Module.cs b/reflect/Module.cs index 7f5acb75..d8460d8c 100644 --- a/reflect/Module.cs +++ b/reflect/Module.cs @@ -287,9 +287,20 @@ namespace IKVM.Reflection public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken); public abstract string ScopeName { get; } - internal abstract Type GetTypeImpl(string typeName); internal abstract void GetTypesImpl(List list); + internal Type GetTypeImpl(string typeName) + { + Type type = FindType(TypeName.Split(TypeNameParser.Unescape(typeName))); + if (type == null && __IsMissing) + { + throw new MissingModuleException((MissingModule)this); + } + return type; + } + + internal abstract Type FindType(TypeName name); + public Type GetType(string className) { return GetType(className, false, false); diff --git a/reflect/Reader/AssemblyReader.cs b/reflect/Reader/AssemblyReader.cs index 08d66ddf..0905895e 100644 --- a/reflect/Reader/AssemblyReader.cs +++ b/reflect/Reader/AssemblyReader.cs @@ -101,14 +101,14 @@ namespace IKVM.Reflection.Reader return list.ToArray(); } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { - Type type = manifestModule.GetType(typeName); + Type type = manifestModule.FindType(typeName); for (int i = 0; type == null && i < externalModules.Length; i++) { if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0) { - type = GetModule(i).GetType(typeName); + type = GetModule(i).FindType(typeName); } } return type; diff --git a/reflect/Reader/GenericTypeParameter.cs b/reflect/Reader/GenericTypeParameter.cs index 2f961f94..cbed322a 100644 --- a/reflect/Reader/GenericTypeParameter.cs +++ b/reflect/Reader/GenericTypeParameter.cs @@ -131,7 +131,7 @@ namespace IKVM.Reflection.Reader get { throw new InvalidOperationException(); } } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { throw new InvalidOperationException(); } diff --git a/reflect/Reader/ModuleReader.cs b/reflect/Reader/ModuleReader.cs index 87f38e62..987244d4 100644 --- a/reflect/Reader/ModuleReader.cs +++ b/reflect/Reader/ModuleReader.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2009-2010 Jeroen Frijters + Copyright (C) 2009-2011 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -74,8 +74,8 @@ namespace IKVM.Reflection.Reader private MethodBase[] methods; private MemberInfo[] memberRefs; private Dictionary strings = new Dictionary(); - private Dictionary types = new Dictionary(); - private Dictionary forwardedTypes = new Dictionary(); + private Dictionary types = new Dictionary(); + private Dictionary forwardedTypes = new Dictionary(); private sealed class LazyForwardedType { @@ -87,12 +87,16 @@ namespace IKVM.Reflection.Reader this.assemblyRef = assemblyRef; } - internal Type GetType(ModuleReader module, string typeName) + internal Type GetType(ModuleReader module, TypeName typeName) { if (type == null) { Assembly asm = module.ResolveAssemblyRef(assemblyRef); - type = asm.GetType(typeName, true); + type = asm.ResolveType(typeName); + if (type == null) + { + throw new TypeLoadException(typeName.ToString()); + } } return type; } @@ -251,9 +255,9 @@ namespace IKVM.Reflection.Reader { moduleType = type; } - else + else if (!type.IsNestedByFlags) { - types.Add(type.FullName, type); + types.Add(new TypeName(type.__Namespace, type.__Name), type); } } // add forwarded types to forwardedTypes dictionary (because Module.GetType(string) should return them) @@ -262,8 +266,8 @@ namespace IKVM.Reflection.Reader int implementation = ExportedType.records[i].Implementation; if (implementation >> 24 == AssemblyRefTable.Index) { - string typeName = GetTypeName(ExportedType.records[i].TypeNamespace, ExportedType.records[i].TypeName); - forwardedTypes.Add(TypeNameParser.Escape(typeName), new LazyForwardedType((implementation & 0xFFFFFF) - 1)); + TypeName typeName = GetTypeName(ExportedType.records[i].TypeNamespace, ExportedType.records[i].TypeName); + forwardedTypes.Add(typeName, new LazyForwardedType((implementation & 0xFFFFFF) - 1)); } } } @@ -362,10 +366,10 @@ namespace IKVM.Reflection.Reader case AssemblyRefTable.Index: { Assembly assembly = ResolveAssemblyRef((scope & 0xFFFFFF) - 1); - Type type = assembly.ResolveType(GetString(TypeRef.records[index].TypeNameSpace), GetString(TypeRef.records[index].TypeName)); + TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); + Type type = assembly.ResolveType(typeName); if (type == null) { - string typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); throw new TypeLoadException(String.Format("Type '{0}' not found in assembly '{1}'", typeName, assembly.FullName)); } typeRefs[index] = type; @@ -374,7 +378,8 @@ namespace IKVM.Reflection.Reader case TypeRefTable.Index: { Type outer = ResolveType(scope, null); - typeRefs[index] = outer.ResolveNestedType(GetString(TypeRef.records[index].TypeNameSpace), GetString(TypeRef.records[index].TypeName)); + TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); + typeRefs[index] = outer.ResolveNestedType(typeName); break; } case ModuleTable.Index: @@ -382,13 +387,13 @@ namespace IKVM.Reflection.Reader { throw new NotImplementedException("self reference scope?"); } - typeRefs[index] = GetType(TypeNameParser.Escape(GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName))); + typeRefs[index] = FindType(GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName)); break; case ModuleRefTable.Index: { Module module = ResolveModuleRef(ModuleRef.records[(scope & 0xFFFFFF) - 1]); - string typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); - Type type = module.GetType(TypeNameParser.Escape(typeName)); + TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); + Type type = module.FindType(typeName); if (type == null) { throw new TypeLoadException(String.Format("Type '{0}' not found in module '{1}'", typeName, module.Name)); @@ -477,16 +482,9 @@ namespace IKVM.Reflection.Reader } } - private string GetTypeName(int typeNamespace, int typeName) + private TypeName GetTypeName(int typeNamespace, int typeName) { - if (typeNamespace == 0) - { - return GetString(typeName); - } - else - { - return GetString(typeNamespace) + "." + GetString(typeName); - } + return new TypeName(GetString(typeNamespace), GetString(typeName)); } private Assembly ResolveAssemblyRef(int index) @@ -561,7 +559,7 @@ namespace IKVM.Reflection.Reader get { return assembly; } } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { PopulateTypeDef(); Type type; @@ -981,21 +979,21 @@ namespace IKVM.Reflection.Reader public override IList __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security) { - string typeName; + TypeName typeName; switch ((multiple ? 1 : 0) + (security ? 2 : 0)) { case 0: - typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHere"; + typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHere"); break; case 1: - typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHereM"; + typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereM"); break; case 2: - typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHereS"; + typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereS"); break; case 3: default: - typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHereSM"; + typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereSM"); break; } List list = new List(); diff --git a/reflect/Reader/ResourceModule.cs b/reflect/Reader/ResourceModule.cs index e80170d2..386e5ca2 100644 --- a/reflect/Reader/ResourceModule.cs +++ b/reflect/Reader/ResourceModule.cs @@ -110,7 +110,7 @@ namespace IKVM.Reflection.Reader throw new NotSupportedException(); } - internal override Type GetTypeImpl(string typeName) + internal override Type FindType(TypeName typeName) { return null; } diff --git a/reflect/Reader/TypeDefImpl.cs b/reflect/Reader/TypeDefImpl.cs index 6a0fbc34..fd008621 100644 --- a/reflect/Reader/TypeDefImpl.cs +++ b/reflect/Reader/TypeDefImpl.cs @@ -305,12 +305,17 @@ namespace IKVM.Reflection.Reader return sb.ToString(); } + internal bool IsNestedByFlags + { + get { return (this.Attributes & TypeAttributes.VisibilityMask & ~TypeAttributes.Public) != 0; } + } + public override Type DeclaringType { get { // note that we cannot use Type.IsNested for this, because that calls DeclaringType - if ((this.Attributes & TypeAttributes.VisibilityMask & ~TypeAttributes.Public) == 0) + if (!IsNestedByFlags) { return null; } diff --git a/reflect/Type.cs b/reflect/Type.cs index 20f1574b..6cc25c4c 100644 --- a/reflect/Type.cs +++ b/reflect/Type.cs @@ -747,35 +747,17 @@ namespace IKVM.Reflection return GetConstructor(bindingAttr, binder, types, modifiers); } - private static bool MatchTypeNames(string ns, string name, string fullName) + internal virtual Type ResolveNestedType(TypeName typeName) { - if (ns == null) - { - return name == fullName; - } - else if (ns.Length + 1 + name.Length == fullName.Length) - { - return fullName[ns.Length] == '.' - && String.CompareOrdinal(ns, 0, fullName, 0, ns.Length) == 0 - && String.CompareOrdinal(name, 0, fullName, ns.Length + 1, name.Length) == 0; - } - else - { - return false; - } - } - - internal virtual Type ResolveNestedType(string ns, string name) - { - return GetNestedTypeCorrectly(ns == null ? name : ns + "." + name); + return FindNestedType(typeName); } // unlike the public API, this takes the namespace and name into account - internal Type GetNestedTypeCorrectly(string name) + internal Type FindNestedType(TypeName name) { foreach (Type type in __GetDeclaredTypes()) { - if (MatchTypeNames(type.__Namespace, type.__Name, name)) + if (type.__Namespace == name.Namespace && type.__Name == name.Name) { return type; } diff --git a/reflect/TypeNameParser.cs b/reflect/TypeNameParser.cs index 77686f03..025d7f69 100644 --- a/reflect/TypeNameParser.cs +++ b/reflect/TypeNameParser.cs @@ -1,5 +1,5 @@ /* - Copyright (C) 2009 Jeroen Frijters + Copyright (C) 2009-2011 Jeroen Frijters This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -27,6 +27,79 @@ using System.Text; namespace IKVM.Reflection { + // this respresents a type name as in metadata: + // - ns will be null for empty the namespace (never the empty string) + // - the strings are not escaped + struct TypeName : IEquatable + { + private readonly string ns; + private readonly string name; + + internal TypeName(string ns, string name) + { + if (name == null) + { + throw new ArgumentNullException("name"); + } + this.ns = ns; + this.name = name; + } + + internal string Name + { + get { return name; } + } + + internal string Namespace + { + get { return ns; } + } + + public static bool operator ==(TypeName o1, TypeName o2) + { + return o1.ns == o2.ns && o1.name == o2.name; + } + + public static bool operator !=(TypeName o1, TypeName o2) + { + return o1.ns != o2.ns || o1.name != o2.name; + } + + public override int GetHashCode() + { + return ns == null ? name.GetHashCode() : ns.GetHashCode() * 37 + name.GetHashCode(); + } + + public override bool Equals(object obj) + { + TypeName? other = obj as TypeName?; + return other != null && other.Value == this; + } + + public override string ToString() + { + return ns == null ? name : ns + "." + name; + } + + bool IEquatable.Equals(TypeName other) + { + return this == other; + } + + internal static TypeName Split(string name) + { + int dot = name.LastIndexOf('.'); + if (dot == -1) + { + return new TypeName(null, name); + } + else + { + return new TypeName(name.Substring(0, dot), name.Substring(dot + 1)); + } + } + } + struct TypeNameParser { private const string SpecialChars = "\\+,[]*&"; @@ -407,7 +480,7 @@ namespace IKVM.Reflection { foreach (string nest in nested) { - type = type.GetNestedTypeCorrectly(TypeNameParser.Unescape(nest)); + type = type.FindNestedType(TypeName.Split(TypeNameParser.Unescape(nest))); if (type == null) { if (throwOnError) diff --git a/reflect/Universe.cs b/reflect/Universe.cs index 4e32b79b..1aed38f8 100644 --- a/reflect/Universe.cs +++ b/reflect/Universe.cs @@ -149,7 +149,11 @@ namespace IKVM.Reflection private Type ImportMscorlibType(System.Type type) { - return Mscorlib.GetTypeImpl(type.FullName); + // We use FindType instead of ResolveType here, because on some versions of mscorlib some of + // the special types we use/support are missing and the type properties are defined to + // return null in that case. + // Note that we don't have to unescape type.Name here, because none of the names contain special characters. + return Mscorlib.FindType(new TypeName(type.Namespace, type.Name)); } internal Type System_Object