Пример #1
0
 internal TypeWrapper DoLoad(string name)
 {
     for (int i = 0; i < modules.Length; i++)
     {
         if (isJavaModule[i])
         {
             Type type = GetJavaType(modules[i], name);
             if (type != null)
             {
                 // check the name to make sure that the canonical name was used
                 if (CompiledTypeWrapper.GetName(type) == name)
                 {
                     return(CompiledTypeWrapper.newInstance(name, type));
                 }
             }
         }
         else
         {
             // TODO should we catch ArgumentException and prohibit array, pointer and byref here?
             Type type = GetType(modules[i], DotNetTypeWrapper.DemangleTypeName(name));
             if (type != null && DotNetTypeWrapper.IsAllowedOutside(type))
             {
                 // check the name to make sure that the canonical name was used
                 if (DotNetTypeWrapper.GetName(type) == name)
                 {
                     return(DotNetTypeWrapper.Create(type, name));
                 }
             }
         }
     }
     if (hasDotNetModule)
     {
         // for fake types, we load the declaring outer type (the real one) and
         // let that generated the manufactured nested classes
         // (note that for generic outer types, we need to duplicate this in ClassLoaderWrapper.LoadGenericClass)
         TypeWrapper outer = null;
         if (name.EndsWith(DotNetTypeWrapper.DelegateInterfaceSuffix))
         {
             outer = DoLoad(name.Substring(0, name.Length - DotNetTypeWrapper.DelegateInterfaceSuffix.Length));
         }
         else if (name.EndsWith(DotNetTypeWrapper.AttributeAnnotationSuffix))
         {
             outer = DoLoad(name.Substring(0, name.Length - DotNetTypeWrapper.AttributeAnnotationSuffix.Length));
         }
         else if (name.EndsWith(DotNetTypeWrapper.AttributeAnnotationReturnValueSuffix))
         {
             outer = DoLoad(name.Substring(0, name.Length - DotNetTypeWrapper.AttributeAnnotationReturnValueSuffix.Length));
         }
         else if (name.EndsWith(DotNetTypeWrapper.AttributeAnnotationMultipleSuffix))
         {
             outer = DoLoad(name.Substring(0, name.Length - DotNetTypeWrapper.AttributeAnnotationMultipleSuffix.Length));
         }
         else if (name.EndsWith(DotNetTypeWrapper.EnumEnumSuffix))
         {
             outer = DoLoad(name.Substring(0, name.Length - DotNetTypeWrapper.EnumEnumSuffix.Length));
         }
         if (outer != null && outer.IsFakeTypeContainer)
         {
             foreach (TypeWrapper tw in outer.InnerClasses)
             {
                 if (tw.Name == name)
                 {
                     return(tw);
                 }
             }
         }
     }
     return(null);
 }
Пример #2
0
        internal TypeWrapper LoadGenericClass(string name)
        {
            // generic class name grammar:
            //
            // mangled(open_generic_type_name) "_$$$_" M(parameter_class_name) ( "_$$_" M(parameter_class_name) )* "_$$$$_"
            //
            // mangled() is the normal name mangling algorithm
            // M() is a replacement of "__" with "$$005F$$005F" followed by a replace of "." with "__"
            //
            int pos = name.IndexOf("_$$$_");

            if (pos <= 0 || !name.EndsWith("_$$$$_"))
            {
                return(null);
            }
            Type type = GetGenericTypeDefinition(DotNetTypeWrapper.DemangleTypeName(name.Substring(0, pos)));

            if (type == null)
            {
                return(null);
            }
            List <string> typeParamNames = new List <string>();

            pos += 5;
            int start = pos;
            int nest  = 0;

            for (;;)
            {
                pos = name.IndexOf("_$$", pos);
                if (pos == -1)
                {
                    return(null);
                }
                if (name.IndexOf("_$$_", pos, 4) == pos)
                {
                    if (nest == 0)
                    {
                        typeParamNames.Add(name.Substring(start, pos - start));
                        start = pos + 4;
                    }
                    pos += 4;
                }
                else if (name.IndexOf("_$$$_", pos, 5) == pos)
                {
                    nest++;
                    pos += 5;
                }
                else if (name.IndexOf("_$$$$_", pos, 6) == pos)
                {
                    if (nest == 0)
                    {
                        if (pos + 6 != name.Length)
                        {
                            return(null);
                        }
                        typeParamNames.Add(name.Substring(start, pos - start));
                        break;
                    }
                    nest--;
                    pos += 6;
                }
                else
                {
                    pos += 3;
                }
            }
            Type[] typeArguments = new Type[typeParamNames.Count];
            for (int i = 0; i < typeArguments.Length; i++)
            {
                string s = (string)typeParamNames[i];
                // only do the unmangling for non-generic types (because we don't want to convert
                // the double underscores in two adjacent _$$$_ or _$$$$_ markers)
                if (s.IndexOf("_$$$_") == -1)
                {
                    s = s.Replace("__", ".");
                    s = s.Replace("$$005F$$005F", "__");
                }
                int dims = 0;
                while (s.Length > dims && s[dims] == 'A')
                {
                    dims++;
                }
                if (s.Length == dims)
                {
                    return(null);
                }
                TypeWrapper tw = null;
                switch (s[dims])
                {
                case 'L':
                    tw = LoadClassByDottedNameFast(s.Substring(dims + 1));
                    tw.Finish();
                    break;

                case 'Z':
                    tw = PrimitiveTypeWrapper.BOOLEAN;
                    break;

                case 'B':
                    tw = PrimitiveTypeWrapper.BYTE;
                    break;

                case 'S':
                    tw = PrimitiveTypeWrapper.SHORT;
                    break;

                case 'C':
                    tw = PrimitiveTypeWrapper.CHAR;
                    break;

                case 'I':
                    tw = PrimitiveTypeWrapper.INT;
                    break;

                case 'F':
                    tw = PrimitiveTypeWrapper.FLOAT;
                    break;

                case 'J':
                    tw = PrimitiveTypeWrapper.LONG;
                    break;

                case 'D':
                    tw = PrimitiveTypeWrapper.DOUBLE;
                    break;
                }
                if (tw == null)
                {
                    return(null);
                }
                if (dims > 0)
                {
                    tw = tw.MakeArrayType(dims);
                }
                typeArguments[i] = tw.TypeAsSignatureType;
            }
            try
            {
                type = type.MakeGenericType(typeArguments);
            }
            catch (ArgumentException)
            {
                // one of the typeArguments failed to meet the constraints
                return(null);
            }
            TypeWrapper wrapper = GetWrapperFromType(type);

            if (wrapper != null && wrapper.Name != name)
            {
                // the name specified was not in canonical form
                return(null);
            }
            return(wrapper);
        }