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.

This commit is contained in:
jfrijters 2011-01-20 05:38:11 +00:00
Родитель 2d876687ad
Коммит d7848c305e
14 изменённых файлов: 224 добавлений и 108 удалений

Просмотреть файл

@ -50,15 +50,29 @@ namespace IKVM.Reflection
public abstract ManifestResourceInfo GetManifestResourceInfo(string resourceName); public abstract ManifestResourceInfo GetManifestResourceInfo(string resourceName);
public abstract System.IO.Stream GetManifestResourceStream(string resourceName); public abstract System.IO.Stream GetManifestResourceStream(string resourceName);
internal abstract Type GetTypeImpl(string typeName); internal 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)
{ {
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() public Module[] GetModules()

Просмотреть файл

@ -64,7 +64,7 @@ namespace IKVM.Reflection.Emit
private readonly List<CustomAttributeBuilder> customAttributes = new List<CustomAttributeBuilder>(); private readonly List<CustomAttributeBuilder> customAttributes = new List<CustomAttributeBuilder>();
private readonly List<CustomAttributeBuilder> declarativeSecurity = new List<CustomAttributeBuilder>(); private readonly List<CustomAttributeBuilder> declarativeSecurity = new List<CustomAttributeBuilder>();
private readonly List<Type> typeForwarders = new List<Type>(); private readonly List<Type> typeForwarders = new List<Type>();
private Dictionary<string, Type> missingTypes; private Dictionary<ScopedTypeName, Type> missingTypes;
private struct ResourceFile private struct ResourceFile
{ {
@ -73,6 +73,34 @@ namespace IKVM.Reflection.Emit
internal ResourceAttributes Attributes; internal ResourceAttributes Attributes;
} }
private struct ScopedTypeName : IEquatable<ScopedTypeName>
{
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<ScopedTypeName>)other.Value).Equals(this);
}
public override int GetHashCode()
{
return declaringType == null ? name.GetHashCode() : declaringType.GetHashCode() * 7 + name.GetHashCode();
}
bool IEquatable<ScopedTypeName>.Equals(ScopedTypeName other)
{
return other.declaringType == declaringType && other.name == name;
}
}
internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions) internal AssemblyBuilder(Universe universe, AssemblyName name, string dir, PermissionSet requiredPermissions, PermissionSet optionalPermissions, PermissionSet refusedPermissions)
: base(universe) : base(universe)
{ {
@ -508,11 +536,11 @@ namespace IKVM.Reflection.Emit
return list.ToArray(); return list.ToArray();
} }
internal override Type GetTypeImpl(string typeName) internal override Type FindType(TypeName typeName)
{ {
foreach (ModuleBuilder mb in modules) foreach (ModuleBuilder mb in modules)
{ {
Type type = mb.GetTypeImpl(typeName); Type type = mb.FindType(typeName);
if (type != null) if (type != null)
{ {
return type; return type;
@ -520,7 +548,7 @@ namespace IKVM.Reflection.Emit
} }
foreach (Module module in addedModules) foreach (Module module in addedModules)
{ {
Type type = module.GetTypeImpl(typeName); Type type = module.FindType(typeName);
if (type != null) if (type != null)
{ {
return type; return type;
@ -529,23 +557,23 @@ namespace IKVM.Reflection.Emit
return null; 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) if (missingTypes == null)
{ {
return null; return null;
} }
Type mt = new MissingType(module, declaringType, ns, name); ScopedTypeName stn = new ScopedTypeName(declaringType, name);
Type type; Type type;
if (!missingTypes.TryGetValue(mt.FullName, out type)) if (!missingTypes.TryGetValue(stn, out type))
{ {
missingTypes.Add(mt.FullName, mt); type = new MissingType(module, declaringType, name.Namespace, name.Name);
type = mt; missingTypes.Add(stn, type);
} }
return type; return type;
} }
@ -554,7 +582,7 @@ namespace IKVM.Reflection.Emit
{ {
if (missingTypes == null) if (missingTypes == null)
{ {
missingTypes = new Dictionary<string, Type>(); missingTypes = new Dictionary<ScopedTypeName, Type>();
} }
} }
@ -692,7 +720,7 @@ namespace IKVM.Reflection.Emit
get { return assembly; } get { return assembly; }
} }
internal override Type GetTypeImpl(string typeName) internal override Type FindType(TypeName typeName)
{ {
return null; return null;
} }

Просмотреть файл

@ -48,7 +48,6 @@ namespace IKVM.Reflection.Emit
private readonly List<TypeBuilder> types = new List<TypeBuilder>(); private readonly List<TypeBuilder> types = new List<TypeBuilder>();
private readonly Dictionary<Type, int> typeTokens = new Dictionary<Type, int>(); private readonly Dictionary<Type, int> typeTokens = new Dictionary<Type, int>();
private readonly Dictionary<Type, int> memberRefTypeTokens = new Dictionary<Type, int>(); private readonly Dictionary<Type, int> memberRefTypeTokens = new Dictionary<Type, int>();
private readonly Dictionary<string, TypeBuilder> fullNameToType = new Dictionary<string, TypeBuilder>();
internal readonly ByteBuffer methodBodies = new ByteBuffer(128 * 1024); internal readonly ByteBuffer methodBodies = new ByteBuffer(128 * 1024);
internal readonly List<int> tokenFixupOffsets = new List<int>(); internal readonly List<int> tokenFixupOffsets = new List<int>();
internal readonly ByteBuffer initializedData = new ByteBuffer(512); internal readonly ByteBuffer initializedData = new ByteBuffer(512);
@ -227,7 +226,6 @@ namespace IKVM.Reflection.Emit
{ {
TypeBuilder typeBuilder = new TypeBuilder(owner, ns, name, attr); TypeBuilder typeBuilder = new TypeBuilder(owner, ns, name, attr);
types.Add(typeBuilder); types.Add(typeBuilder);
fullNameToType.Add(typeBuilder.FullName, typeBuilder);
return typeBuilder; return typeBuilder;
} }
@ -433,11 +431,16 @@ namespace IKVM.Reflection.Emit
get { return asm; } get { return asm; }
} }
internal override Type GetTypeImpl(string typeName) internal override Type FindType(TypeName name)
{ {
TypeBuilder type; foreach (Type type in types)
fullNameToType.TryGetValue(typeName, out type); {
return type; if (type.__Namespace == name.Namespace && type.__Name == name.Name)
{
return type;
}
}
return null;
} }
internal override void GetTypesImpl(List<Type> list) internal override void GetTypesImpl(List<Type> list)

Просмотреть файл

@ -1038,9 +1038,9 @@ namespace IKVM.Reflection.Emit
get { return token == 0x02000001; } 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);
} }
} }

Просмотреть файл

@ -98,7 +98,7 @@ namespace IKVM.Reflection
sealed class MissingAssembly : Assembly sealed class MissingAssembly : Assembly
{ {
private readonly Dictionary<string, Type> types = new Dictionary<string, Type>(); private readonly Dictionary<TypeName, Type> types = new Dictionary<TypeName, Type>();
private readonly MissingModule module; private readonly MissingModule module;
private readonly string name; private readonly string name;
@ -109,14 +109,13 @@ namespace IKVM.Reflection
this.name = name; 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; Type type;
if (!types.TryGetValue(fullName, out type)) if (!types.TryGetValue(name, out type))
{ {
type = new MissingType(module, null, ns, name); type = new MissingType(module, null, name.Namespace, name.Name);
types.Add(fullName, type); types.Add(name, type);
} }
return type; return type;
} }
@ -196,9 +195,9 @@ namespace IKVM.Reflection
get { return true; } get { return true; }
} }
internal override Type GetTypeImpl(string typeName) internal override Type FindType(TypeName typeName)
{ {
throw new MissingAssemblyException(this); return null;
} }
internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType) internal override IList<CustomAttributeData> GetCustomAttributesData(Type attributeType)
@ -277,9 +276,9 @@ namespace IKVM.Reflection
get { throw new MissingModuleException(this); } 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<Type> list) internal override void GetTypesImpl(System.Collections.Generic.List<Type> list)
@ -354,7 +353,7 @@ namespace IKVM.Reflection
private readonly Type declaringType; private readonly Type declaringType;
private readonly string ns; private readonly string ns;
private readonly string name; private readonly string name;
private Dictionary<string, Type> types; private Dictionary<TypeName, Type> types;
internal MissingType(Module module, Type declaringType, string ns, string name) internal MissingType(Module module, Type declaringType, string ns, string name)
{ {
@ -364,18 +363,17 @@ namespace IKVM.Reflection
this.name = name; this.name = name;
} }
internal override Type ResolveNestedType(string ns, string name) internal override Type ResolveNestedType(TypeName typeName)
{ {
if (types == null) if (types == null)
{ {
types = new Dictionary<string, Type>(); types = new Dictionary<TypeName, Type>();
} }
string fullName = ns == null ? name : ns + "." + name;
Type type; Type type;
if (!types.TryGetValue(fullName, out type)) if (!types.TryGetValue(typeName, out type))
{ {
type = new MissingType(module, this, ns, name); type = new MissingType(module, this, typeName.Namespace, typeName.Name);
types.Add(fullName, type); types.Add(typeName, type);
} }
return type; return type;
} }

Просмотреть файл

@ -287,9 +287,20 @@ namespace IKVM.Reflection
public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken); public abstract Type[] __ResolveOptionalParameterTypes(int metadataToken);
public abstract string ScopeName { get; } public abstract string ScopeName { get; }
internal abstract Type GetTypeImpl(string typeName);
internal abstract void GetTypesImpl(List<Type> list); internal abstract void GetTypesImpl(List<Type> 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) public Type GetType(string className)
{ {
return GetType(className, false, false); return GetType(className, false, false);

Просмотреть файл

@ -101,14 +101,14 @@ namespace IKVM.Reflection.Reader
return list.ToArray(); 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++) for (int i = 0; type == null && i < externalModules.Length; i++)
{ {
if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0) if ((manifestModule.File.records[i].Flags & ContainsNoMetaData) == 0)
{ {
type = GetModule(i).GetType(typeName); type = GetModule(i).FindType(typeName);
} }
} }
return type; return type;

Просмотреть файл

@ -131,7 +131,7 @@ namespace IKVM.Reflection.Reader
get { throw new InvalidOperationException(); } get { throw new InvalidOperationException(); }
} }
internal override Type GetTypeImpl(string typeName) internal override Type FindType(TypeName typeName)
{ {
throw new InvalidOperationException(); throw new InvalidOperationException();
} }

Просмотреть файл

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages 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 MethodBase[] methods;
private MemberInfo[] memberRefs; private MemberInfo[] memberRefs;
private Dictionary<int, string> strings = new Dictionary<int, string>(); private Dictionary<int, string> strings = new Dictionary<int, string>();
private Dictionary<string, Type> types = new Dictionary<string, Type>(); private Dictionary<TypeName, Type> types = new Dictionary<TypeName, Type>();
private Dictionary<string, LazyForwardedType> forwardedTypes = new Dictionary<string, LazyForwardedType>(); private Dictionary<TypeName, LazyForwardedType> forwardedTypes = new Dictionary<TypeName, LazyForwardedType>();
private sealed class LazyForwardedType private sealed class LazyForwardedType
{ {
@ -87,12 +87,16 @@ namespace IKVM.Reflection.Reader
this.assemblyRef = assemblyRef; this.assemblyRef = assemblyRef;
} }
internal Type GetType(ModuleReader module, string typeName) internal Type GetType(ModuleReader module, TypeName typeName)
{ {
if (type == null) if (type == null)
{ {
Assembly asm = module.ResolveAssemblyRef(assemblyRef); Assembly asm = module.ResolveAssemblyRef(assemblyRef);
type = asm.GetType(typeName, true); type = asm.ResolveType(typeName);
if (type == null)
{
throw new TypeLoadException(typeName.ToString());
}
} }
return type; return type;
} }
@ -251,9 +255,9 @@ namespace IKVM.Reflection.Reader
{ {
moduleType = type; 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) // 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; int implementation = ExportedType.records[i].Implementation;
if (implementation >> 24 == AssemblyRefTable.Index) if (implementation >> 24 == AssemblyRefTable.Index)
{ {
string typeName = GetTypeName(ExportedType.records[i].TypeNamespace, ExportedType.records[i].TypeName); TypeName typeName = GetTypeName(ExportedType.records[i].TypeNamespace, ExportedType.records[i].TypeName);
forwardedTypes.Add(TypeNameParser.Escape(typeName), new LazyForwardedType((implementation & 0xFFFFFF) - 1)); forwardedTypes.Add(typeName, new LazyForwardedType((implementation & 0xFFFFFF) - 1));
} }
} }
} }
@ -362,10 +366,10 @@ namespace IKVM.Reflection.Reader
case AssemblyRefTable.Index: case AssemblyRefTable.Index:
{ {
Assembly assembly = ResolveAssemblyRef((scope & 0xFFFFFF) - 1); 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) 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)); throw new TypeLoadException(String.Format("Type '{0}' not found in assembly '{1}'", typeName, assembly.FullName));
} }
typeRefs[index] = type; typeRefs[index] = type;
@ -374,7 +378,8 @@ namespace IKVM.Reflection.Reader
case TypeRefTable.Index: case TypeRefTable.Index:
{ {
Type outer = ResolveType(scope, null); 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; break;
} }
case ModuleTable.Index: case ModuleTable.Index:
@ -382,13 +387,13 @@ namespace IKVM.Reflection.Reader
{ {
throw new NotImplementedException("self reference scope?"); 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; break;
case ModuleRefTable.Index: case ModuleRefTable.Index:
{ {
Module module = ResolveModuleRef(ModuleRef.records[(scope & 0xFFFFFF) - 1]); Module module = ResolveModuleRef(ModuleRef.records[(scope & 0xFFFFFF) - 1]);
string typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName); TypeName typeName = GetTypeName(TypeRef.records[index].TypeNameSpace, TypeRef.records[index].TypeName);
Type type = module.GetType(TypeNameParser.Escape(typeName)); Type type = module.FindType(typeName);
if (type == null) if (type == null)
{ {
throw new TypeLoadException(String.Format("Type '{0}' not found in module '{1}'", typeName, module.Name)); 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 new TypeName(GetString(typeNamespace), GetString(typeName));
{
return GetString(typeName);
}
else
{
return GetString(typeNamespace) + "." + GetString(typeName);
}
} }
private Assembly ResolveAssemblyRef(int index) private Assembly ResolveAssemblyRef(int index)
@ -561,7 +559,7 @@ namespace IKVM.Reflection.Reader
get { return assembly; } get { return assembly; }
} }
internal override Type GetTypeImpl(string typeName) internal override Type FindType(TypeName typeName)
{ {
PopulateTypeDef(); PopulateTypeDef();
Type type; Type type;
@ -981,21 +979,21 @@ namespace IKVM.Reflection.Reader
public override IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security) public override IList<CustomAttributeData> __GetPlaceholderAssemblyCustomAttributes(bool multiple, bool security)
{ {
string typeName; TypeName typeName;
switch ((multiple ? 1 : 0) + (security ? 2 : 0)) switch ((multiple ? 1 : 0) + (security ? 2 : 0))
{ {
case 0: case 0:
typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHere"; typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHere");
break; break;
case 1: case 1:
typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHereM"; typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereM");
break; break;
case 2: case 2:
typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHereS"; typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereS");
break; break;
case 3: case 3:
default: default:
typeName = "System.Runtime.CompilerServices.AssemblyAttributesGoHereSM"; typeName = new TypeName("System.Runtime.CompilerServices", "AssemblyAttributesGoHereSM");
break; break;
} }
List<CustomAttributeData> list = new List<CustomAttributeData>(); List<CustomAttributeData> list = new List<CustomAttributeData>();

Просмотреть файл

@ -110,7 +110,7 @@ namespace IKVM.Reflection.Reader
throw new NotSupportedException(); throw new NotSupportedException();
} }
internal override Type GetTypeImpl(string typeName) internal override Type FindType(TypeName typeName)
{ {
return null; return null;
} }

Просмотреть файл

@ -305,12 +305,17 @@ namespace IKVM.Reflection.Reader
return sb.ToString(); return sb.ToString();
} }
internal bool IsNestedByFlags
{
get { return (this.Attributes & TypeAttributes.VisibilityMask & ~TypeAttributes.Public) != 0; }
}
public override Type DeclaringType public override Type DeclaringType
{ {
get get
{ {
// note that we cannot use Type.IsNested for this, because that calls DeclaringType // 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; return null;
} }

Просмотреть файл

@ -747,35 +747,17 @@ namespace IKVM.Reflection
return GetConstructor(bindingAttr, binder, types, modifiers); 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 FindNestedType(typeName);
{
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);
} }
// unlike the public API, this takes the namespace and name into account // 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()) foreach (Type type in __GetDeclaredTypes())
{ {
if (MatchTypeNames(type.__Namespace, type.__Name, name)) if (type.__Namespace == name.Namespace && type.__Name == name.Name)
{ {
return type; return type;
} }

Просмотреть файл

@ -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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
@ -27,6 +27,79 @@ using System.Text;
namespace IKVM.Reflection 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<TypeName>
{
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<TypeName>.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 struct TypeNameParser
{ {
private const string SpecialChars = "\\+,[]*&"; private const string SpecialChars = "\\+,[]*&";
@ -407,7 +480,7 @@ namespace IKVM.Reflection
{ {
foreach (string nest in nested) foreach (string nest in nested)
{ {
type = type.GetNestedTypeCorrectly(TypeNameParser.Unescape(nest)); type = type.FindNestedType(TypeName.Split(TypeNameParser.Unescape(nest)));
if (type == null) if (type == null)
{ {
if (throwOnError) if (throwOnError)

Просмотреть файл

@ -149,7 +149,11 @@ namespace IKVM.Reflection
private Type ImportMscorlibType(System.Type type) 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 internal Type System_Object