X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mcs%2Fmcs%2Fimport.cs;h=7a3081c7cbbf8d660c279480fcf9446993c0a097;hb=f574f7b447e29c6f083fcad4e6dc5f89d3cb4b4d;hp=12cd52fc680a5dd1a3dde6311fa5e56aca43fb8c;hpb=3bd0546e18538f5c04fdc522896a1565b1a86b85;p=mono.git diff --git a/mcs/mcs/import.cs b/mcs/mcs/import.cs index 12cd52fc680..7a3081c7cbb 100644 --- a/mcs/mcs/import.cs +++ b/mcs/mcs/import.cs @@ -5,7 +5,8 @@ // // Dual licensed under the terms of the MIT X11 or GNU GPL // -// Copyright 2009, 2010 Novell, Inc +// Copyright 2009-2011 Novell, Inc +// Copyright 2011 Xamarin, Inc (http://www.xamarin.com) // using System; @@ -87,10 +88,9 @@ namespace Mono.CSharp } if (cad.Count > 0) { - string ns, name; foreach (var ca in cad) { - importer.GetCustomAttributeTypeName (ca, out ns, out name); - if (name != "DynamicAttribute" && ns != CompilerServicesNamespace) + var dt = ca.Constructor.DeclaringType; + if (dt.Name != "DynamicAttribute" && dt.Namespace != CompilerServicesNamespace) continue; if (ca.ConstructorArguments.Count == 0) { @@ -149,7 +149,6 @@ namespace Mono.CSharp public abstract void AddCompiledType (TypeBuilder builder, TypeSpec spec); protected abstract MemberKind DetermineKindFromBaseType (MetaType baseType); protected abstract bool HasVolatileModifier (MetaType[] modifiers); - public abstract void GetCustomAttributeTypeName (CustomAttributeData cad, out string typeNamespace, out string typeName); public FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType) { @@ -170,7 +169,8 @@ namespace Mono.CSharp break; default: // Ignore private fields (even for error reporting) to not require extra dependencies - if (IgnorePrivateMembers || HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace)) + if ((IgnorePrivateMembers && !declaringType.IsStruct) || + HasAttribute (CustomAttributeData.GetCustomAttributes (fi), "CompilerGeneratedAttribute", CompilerServicesNamespace)) return null; mod = Modifiers.PRIVATE; @@ -387,20 +387,30 @@ namespace Mono.CSharp // Cannot set to OVERRIDE without full hierarchy checks // this flag indicates that the method could be override // but further validation is needed - if ((mod & Modifiers.OVERRIDE) != 0 && kind == MemberKind.Method && declaringType.BaseType != null) { - var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null); - var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None); + if ((mod & Modifiers.OVERRIDE) != 0) { + bool is_real_override = false; + if (kind == MemberKind.Method && declaringType.BaseType != null) { + var filter = MemberFilter.Method (name, tparams != null ? tparams.Length : 0, parameters, null); + var candidate = MemberCache.FindMember (declaringType.BaseType, filter, BindingRestriction.None); - // - // For imported class method do additional validation to be sure that metadata - // override flag was correct - // - // Difference between protected internal and protected is ok - // - const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL; - if (candidate == null || (candidate.Modifiers & conflict_mask) != (mod & conflict_mask) || candidate.IsStatic) { + // + // For imported class method do additional validation to be sure that metadata + // override flag was correct + // + // Difference between protected internal and protected is ok + // + const Modifiers conflict_mask = Modifiers.AccessibilityMask & ~Modifiers.INTERNAL; + if (candidate != null && (candidate.Modifiers & conflict_mask) == (mod & conflict_mask) && !candidate.IsStatic) { + is_real_override = true; + } + } + + if (!is_real_override) { mod &= ~Modifiers.OVERRIDE; - mod |= Modifiers.VIRTUAL; + if ((mod & Modifiers.SEALED) != 0) + mod &= ~Modifiers.SEALED; + else + mod |= Modifiers.VIRTUAL; } } } @@ -469,7 +479,7 @@ namespace Mono.CSharp if (!is_params && p.IsOptional) { object value = p.RawDefaultValue; var ptype = types[i]; - if ((p.Attributes & ParameterAttributes.HasDefault) != 0 && ptype.Kind != MemberKind.TypeParameter && (value != null || TypeManager.IsReferenceType (ptype))) { + if ((p.Attributes & ParameterAttributes.HasDefault) != 0 && ptype.Kind != MemberKind.TypeParameter && (value != null || TypeSpec.IsReferenceType (ptype))) { if (value == null) { default_value = Constant.CreateConstant (ptype, null, Location.Null); } else { @@ -607,7 +617,7 @@ namespace Mono.CSharp spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi, type, this), type, pi, mod); if (!is_valid_property) { - spec.IsNotRealProperty = true; + spec.IsNotCSharpCompatible = true; return spec; } @@ -673,6 +683,11 @@ namespace Mono.CSharp if (type.IsGenericType && !type.IsGenericTypeDefinition) { var type_def = type.GetGenericTypeDefinition (); + + // Generic type definition can also be forwarded + if (compiled_types.TryGetValue (type_def, out spec)) + return spec; + var targs = CreateGenericArguments (0, type.GetGenericArguments (), dtype); if (declaringType == null) { // Simple case, no nesting @@ -713,6 +728,9 @@ namespace Mono.CSharp name = name.Substring (0, index); spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos); + if (spec == null) + return null; + if (spec.Arity > 0) { spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ()); } @@ -835,7 +853,7 @@ namespace Mono.CSharp if (!assembly_2_definition.TryGetValue (assembly, out found)) { // This can happen in dynamic context only - var def = new ImportedAssemblyDefinition (assembly, this); + var def = new ImportedAssemblyDefinition (assembly); assembly_2_definition.Add (assembly, def); def.ReadAttributes (); found = def; @@ -899,10 +917,9 @@ namespace Mono.CSharp if (attributesData.Count == 0) return false; - string ns, name; foreach (var attr in attributesData) { - GetCustomAttributeTypeName (attr, out ns, out name); - if (name == attrName && ns == attrNamespace) + var dt = attr.Constructor.DeclaringType; + if (dt.Name == attrName && dt.Namespace == attrNamespace) return true; } @@ -929,9 +946,12 @@ namespace Mono.CSharp if (ifaces.Length != 0) { foreach (var iface in ifaces) { var it = CreateType (iface); + if (it == null) + continue; + spec.AddInterface (it); - // Unfortunatelly not all languages inlcude inherited interfaces + // Unfortunately not all languages expand inherited interfaces var bifaces = it.Interfaces; if (bifaces != null) { foreach (var biface in bifaces) { @@ -944,6 +964,15 @@ namespace Mono.CSharp if (spec.BaseType != null) { var bifaces = spec.BaseType.Interfaces; if (bifaces != null) { + // + // Before adding base class interfaces close defined interfaces + // on type parameter + // + var tp = spec as TypeParameterSpec; + if (tp != null && tp.InterfacesDefined == null) { + tp.InterfacesDefined = TypeSpec.EmptyTypes; + } + foreach (var iface in bifaces) spec.AddInterface (iface); } @@ -990,7 +1019,7 @@ namespace Mono.CSharp prev_namespace = t.Namespace; } - ns.AddType (it); + ns.AddType (module, it); if (it.IsStatic && hasExtensionTypes && HasAttribute (CustomAttributeData.GetCustomAttributes (t), "ExtensionAttribute", CompilerServicesNamespace)) { @@ -1112,10 +1141,9 @@ namespace Mono.CSharp if (attrs.Count == 0) return null; - string name, ns; foreach (var ca in attrs) { - GetCustomAttributeTypeName (ca, out ns, out name); - if (name != "DecimalConstantAttribute" || ns != CompilerServicesNamespace) + var dt = ca.Constructor.DeclaringType; + if (dt.Name != "DecimalConstantAttribute" || dt.Namespace != CompilerServicesNamespace) continue; var value = new decimal ( @@ -1162,15 +1190,21 @@ namespace Mono.CSharp return mod; } + // It can be sealed and override if ((ma & MethodAttributes.Final) != 0) mod |= Modifiers.SEALED; - // It can be sealed and override if ((ma & MethodAttributes.Virtual) != 0) { - if ((ma & MethodAttributes.NewSlot) != 0 || !declaringType.IsClass) { - // No private virtual or sealed virtual - if ((mod & (Modifiers.PRIVATE | Modifiers.SEALED)) == 0) + // Not every member can be detected based on MethodAttribute, we + // set virtual or non-virtual only when we are certain. Further checks + // to really find out what `virtual' means for this member are done + // later + if ((ma & MethodAttributes.NewSlot) != 0) { + if ((mod & Modifiers.SEALED) != 0) { + mod &= ~Modifiers.SEALED; + } else { mod |= Modifiers.VIRTUAL; + } } else { mod |= Modifiers.OVERRIDE; } @@ -1201,11 +1235,11 @@ namespace Mono.CSharp // It should not throw any loading exception IList attrs = CustomAttributeData.GetCustomAttributes (mi); - string ns, name; foreach (var a in attrs) { - importer.GetCustomAttributeTypeName (a, out ns, out name); + var dt = a.Constructor.DeclaringType; + string name = dt.Name; if (name == "ObsoleteAttribute") { - if (ns != "System") + if (dt.Namespace != "System") continue; if (bag == null) @@ -1225,7 +1259,7 @@ namespace Mono.CSharp } if (name == "ConditionalAttribute") { - if (ns != "System.Diagnostics") + if (dt.Namespace != "System.Diagnostics") continue; if (bag == null) @@ -1239,7 +1273,7 @@ namespace Mono.CSharp } if (name == "CLSCompliantAttribute") { - if (ns != "System") + if (dt.Namespace != "System") continue; if (bag == null) @@ -1252,7 +1286,7 @@ namespace Mono.CSharp // Type only attributes if (mi.MemberType == MemberTypes.TypeInfo || mi.MemberType == MemberTypes.NestedType) { if (name == "DefaultMemberAttribute") { - if (ns != "System.Reflection") + if (dt.Namespace != "System.Reflection") continue; if (bag == null) @@ -1263,7 +1297,7 @@ namespace Mono.CSharp } if (name == "AttributeUsageAttribute") { - if (ns != "System") + if (dt.Namespace != "System") continue; if (bag == null) @@ -1281,7 +1315,7 @@ namespace Mono.CSharp // Interface only attribute if (name == "CoClassAttribute") { - if (ns != "System.Runtime.InteropServices") + if (dt.Namespace != "System.Runtime.InteropServices") continue; if (bag == null) @@ -1374,12 +1408,10 @@ namespace Mono.CSharp { readonly Module module; bool cls_compliant; - readonly MetadataImporter importer; - public ImportedModuleDefinition (Module module, MetadataImporter importer) + public ImportedModuleDefinition (Module module) { this.module = module; - this.importer = importer; } #region Properties @@ -1402,11 +1434,10 @@ namespace Mono.CSharp { IList attrs = CustomAttributeData.GetCustomAttributes (module); - string ns, name; foreach (var a in attrs) { - importer.GetCustomAttributeTypeName (a, out ns, out name); - if (name == "CLSCompliantAttribute") { - if (ns != "System") + var dt = a.Constructor.DeclaringType; + if (dt.Name == "CLSCompliantAttribute") { + if (dt.Namespace != "System") continue; cls_compliant = (bool) a.ConstructorArguments[0].Value; @@ -1455,18 +1486,16 @@ namespace Mono.CSharp { readonly Assembly assembly; readonly AssemblyName aname; - readonly MetadataImporter importer; bool cls_compliant; bool contains_extension_methods; List internals_visible_to; Dictionary internals_visible_to_cache; - public ImportedAssemblyDefinition (Assembly assembly, MetadataImporter importer) + public ImportedAssemblyDefinition (Assembly assembly) { this.assembly = assembly; this.aname = assembly.GetName (); - this.importer = importer; } #region Properties @@ -1581,31 +1610,21 @@ namespace Mono.CSharp IList attrs = CustomAttributeData.GetCustomAttributes (assembly); - string ns, name; foreach (var a in attrs) { - importer.GetCustomAttributeTypeName (a, out ns, out name); - + var dt = a.Constructor.DeclaringType; + var name = dt.Name; if (name == "CLSCompliantAttribute") { - if (ns == "System") { - try { - cls_compliant = (bool) a.ConstructorArguments[0].Value; - } catch { - } + if (dt.Namespace == "System") { + cls_compliant = (bool) a.ConstructorArguments[0].Value; } continue; } if (name == "InternalsVisibleToAttribute") { - if (ns != MetadataImporter.CompilerServicesNamespace) + if (dt.Namespace != MetadataImporter.CompilerServicesNamespace) continue; - string s; - try { - s = a.ConstructorArguments[0].Value as string; - } catch { - s = null; - } - + string s = a.ConstructorArguments[0].Value as string; if (s == null) continue; @@ -1618,7 +1637,7 @@ namespace Mono.CSharp } if (name == "ExtensionAttribute") { - if (ns == MetadataImporter.CompilerServicesNamespace) + if (dt.Namespace == MetadataImporter.CompilerServicesNamespace) contains_extension_methods = true; continue; @@ -1869,7 +1888,13 @@ namespace Mono.CSharp if ((t.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate && importer.IgnorePrivateMembers) continue; - imported = importer.CreateNestedType (t, declaringType); + try { + imported = importer.CreateNestedType (t, declaringType); + } catch (Exception e) { + throw new InternalErrorException (e, "Could not import nested type `{0}' from `{1}'", + t.FullName, declaringType.MemberDefinition.DeclaringAssembly.FullName); + } + cache.AddMemberImported (imported); } @@ -1886,6 +1911,15 @@ namespace Mono.CSharp } } + // + // Load base interfaces first to minic behaviour of compiled members + // + if (declaringType.IsInterface && declaringType.Interfaces != null) { + foreach (var iface in declaringType.Interfaces) { + cache.AddInterface (iface); + } + } + if (!onlyTypes) { // // The logic here requires methods to be returned first which seems to work for both Mono and .NET @@ -2016,12 +2050,6 @@ namespace Mono.CSharp cache.AddMemberImported (imported); } } - - if (declaringType.IsInterface && declaringType.Interfaces != null) { - foreach (var iface in declaringType.Interfaces) { - cache.AddInterface (iface); - } - } } }