Update mcs/class/System.Core/System/TimeZoneInfo.cs
[mono.git] / mcs / class / IKVM.Reflection / TypeNameParser.cs
index 025d7f693761fc0832562a3c933fb76a39b3e8c0..781fe1b358873c08a71a13381e7b52ec6f6b8596 100644 (file)
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2009-2011 Jeroen Frijters
+  Copyright (C) 2009-2012 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
@@ -23,6 +23,7 @@
 */
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
 using System.Text;
 
 namespace IKVM.Reflection
@@ -86,6 +87,11 @@ namespace IKVM.Reflection
                        return this == other;
                }
 
+               internal TypeName ToLowerInvariant()
+               {
+                       return new TypeName(ns == null ? null : ns.ToLowerInvariant(), name.ToLowerInvariant());
+               }
+
                internal static TypeName Split(string name)
                {
                        int dot = name.LastIndexOf('.');
@@ -122,17 +128,27 @@ namespace IKVM.Reflection
                        for (int pos = 0; pos < name.Length; pos++)
                        {
                                char c = name[pos];
-                               if (SpecialChars.IndexOf(c) != -1)
-                               {
-                                       if (sb == null)
-                                       {
-                                               sb = new StringBuilder(name, 0, pos, name.Length + 3);
-                                       }
-                                       sb.Append('\\').Append(c);
-                               }
-                               else if (sb != null)
+                               switch (c)
                                {
-                                       sb.Append(c);
+                                       case '\\':
+                                       case '+':
+                                       case ',':
+                                       case '[':
+                                       case ']':
+                                       case '*':
+                                       case '&':
+                                               if (sb == null)
+                                               {
+                                                       sb = new StringBuilder(name, 0, pos, name.Length + 3);
+                                               }
+                                               sb.Append("\\").Append(c);
+                                               break;
+                                       default:
+                                               if (sb != null)
+                                               {
+                                                       sb.Append(c);
+                                               }
+                                               break;
                                }
                        }
                        return sb != null ? sb.ToString() : name;
@@ -439,8 +455,10 @@ namespace IKVM.Reflection
                        }
                }
 
-               internal Type GetType(Universe universe, Assembly context, bool throwOnError, string originalName)
+               internal Type GetType(Universe universe, Assembly context, bool throwOnError, string originalName, bool resolve, bool ignoreCase)
                {
+                       Debug.Assert(!resolve || !ignoreCase);
+                       TypeName name = TypeName.Split(this.name);
                        Type type;
                        if (assemblyName != null)
                        {
@@ -449,25 +467,74 @@ namespace IKVM.Reflection
                                {
                                        return null;
                                }
-                               type = asm.GetTypeImpl(name);
+                               if (resolve)
+                               {
+                                       type = asm.ResolveType(name);
+                               }
+                               else if (ignoreCase)
+                               {
+                                       type = asm.FindTypeIgnoreCase(name.ToLowerInvariant());
+                               }
+                               else
+                               {
+                                       type = asm.FindType(name);
+                               }
                        }
                        else if (context == null)
                        {
-                               type = universe.Mscorlib.GetTypeImpl(name);
+                               if (resolve)
+                               {
+                                       type = universe.Mscorlib.ResolveType(name);
+                               }
+                               else if (ignoreCase)
+                               {
+                                       type = universe.Mscorlib.FindTypeIgnoreCase(name.ToLowerInvariant());
+                               }
+                               else
+                               {
+                                       type = universe.Mscorlib.FindType(name);
+                               }
                        }
                        else
                        {
-                               type = context.GetTypeImpl(name);
+                               if (ignoreCase)
+                               {
+                                       name = name.ToLowerInvariant();
+                                       type = context.FindTypeIgnoreCase(name);
+                               }
+                               else
+                               {
+                                       type = context.FindType(name);
+                               }
                                if (type == null && context != universe.Mscorlib)
                                {
-                                       type = universe.Mscorlib.GetTypeImpl(name);
+                                       if (ignoreCase)
+                                       {
+                                               type = universe.Mscorlib.FindTypeIgnoreCase(name);
+                                       }
+                                       else
+                                       {
+                                               type = universe.Mscorlib.FindType(name);
+                                       }
+                               }
+                               if (type == null && resolve)
+                               {
+                                       if (universe.Mscorlib.__IsMissing && !context.__IsMissing)
+                                       {
+                                               type = universe.Mscorlib.ResolveType(name);
+                                       }
+                                       else
+                                       {
+                                               type = context.ResolveType(name);
+                                       }
                                }
                        }
-                       return Expand(type, context, throwOnError, originalName);
+                       return Expand(type, context, throwOnError, originalName, resolve, ignoreCase);
                }
 
-               internal Type Expand(Type type, Assembly context, bool throwOnError, string originalName)
+               internal Type Expand(Type type, Assembly context, bool throwOnError, string originalName, bool resolve, bool ignoreCase)
                {
+                       Debug.Assert(!resolve || !ignoreCase);
                        if (type == null)
                        {
                                if (throwOnError)
@@ -478,16 +545,28 @@ namespace IKVM.Reflection
                        }
                        if (nested != null)
                        {
+                               Type outer;
                                foreach (string nest in nested)
                                {
-                                       type = type.FindNestedType(TypeName.Split(TypeNameParser.Unescape(nest)));
+                                       outer = type;
+                                       TypeName name = TypeName.Split(TypeNameParser.Unescape(nest));
+                                       type = ignoreCase
+                                               ? outer.FindNestedTypeIgnoreCase(name.ToLowerInvariant())
+                                               : outer.FindNestedType(name);
                                        if (type == null)
                                        {
-                                               if (throwOnError)
+                                               if (resolve)
+                                               {
+                                                       type = outer.Module.universe.GetMissingTypeOrThrow(outer.Module, outer, name);
+                                               }
+                                               else if (throwOnError)
                                                {
                                                        throw new TypeLoadException(originalName);
                                                }
-                                               return null;
+                                               else
+                                               {
+                                                       return null;
+                                               }
                                        }
                                }
                        }
@@ -496,7 +575,7 @@ namespace IKVM.Reflection
                                Type[] typeArgs = new Type[genericParameters.Length];
                                for (int i = 0; i < typeArgs.Length; i++)
                                {
-                                       typeArgs[i] = genericParameters[i].GetType(type.Assembly.universe, context, throwOnError, originalName);
+                                       typeArgs[i] = genericParameters[i].GetType(type.Assembly.universe, context, throwOnError, originalName, resolve, ignoreCase);
                                        if (typeArgs[i] == null)
                                        {
                                                return null;