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); }
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); }