Merge branch 'master' into msbuilddll2
[mono.git] / mcs / mcs / import.cs
index 8474e29a5b44c1467bd04008a1afdc3dbb9169dd..125404f6d920693b7289b968bde5a15fae1ff9c1 100644 (file)
@@ -56,10 +56,10 @@ namespace Mono.CSharp
                        //
                        // Returns true when object at local position has dynamic attribute flag
                        //
-                       public bool IsDynamicObject (MetadataImporter importer)
+                       public bool IsDynamicObject ()
                        {
                                if (provider != null)
-                                       ReadAttribute (importer);
+                                       ReadAttribute ();
 
                                return flags != null && Position < flags.Length && flags[Position];
                        }
@@ -67,15 +67,15 @@ namespace Mono.CSharp
                        //
                        // Returns true when DynamicAttribute exists
                        //
-                       public bool HasDynamicAttribute (MetadataImporter importer)
+                       public bool HasDynamicAttribute ()
                        {
                                if (provider != null)
-                                       ReadAttribute (importer);
+                                       ReadAttribute ();
 
                                return flags != null;
                        }
 
-                       void ReadAttribute (MetadataImporter importer)
+                       void ReadAttribute ()
                        {
                                IList<CustomAttributeData> cad;
                                if (provider is MemberInfo) {
@@ -152,7 +152,7 @@ namespace Mono.CSharp
 
                public FieldSpec CreateField (FieldInfo fi, TypeSpec declaringType)
                {
-                       Modifiers mod = 0;
+                       Modifiers mod;
                        var fa = fi.Attributes;
                        switch (fa & FieldAttributes.FieldAccessMask) {
                                case FieldAttributes.Public:
@@ -220,7 +220,7 @@ namespace Mono.CSharp
 
                                        // TODO: Sanity check on field_type (only few types are allowed)
                                        var element_field = CreateField (fi.FieldType.GetField (FixedField.FixedElementName), declaringType);
-                                       return new FixedFieldSpec (declaringType, definition, fi, element_field, mod);
+                                       return new FixedFieldSpec (module, declaringType, definition, fi, element_field, mod);
                                }
                        }
 
@@ -324,10 +324,9 @@ namespace Mono.CSharp
                                        //    IFoo<A<T>> foo;   // A<T> is definition in this case
                                        // }
                                        //
-                                       // TODO: Is full logic from CreateType needed here as well?
-                                       //
                                        if (!IsMissingType (type) && type.IsGenericTypeDefinition) {
-                                               var targs = CreateGenericArguments (0, type.GetGenericArguments (), dtype);
+                                               var start_pos = spec.DeclaringType == null ? 0 : spec.DeclaringType.MemberDefinition.TypeParametersCount;
+                                               var targs = CreateGenericArguments (start_pos, type.GetGenericArguments (), dtype);
                                                spec = spec.MakeGenericType (module, targs);
                                        }
                                }
@@ -420,7 +419,7 @@ namespace Mono.CSharp
                                }
                        }
 
-                       IMemberDefinition definition;
+                       IMethodDefinition definition;
                        if (tparams != null) {
                                var gmd = new ImportedGenericMethodDefinition ((MethodInfo) mb, returnType, parameters, tparams, this);
                                foreach (var tp in gmd.TypeParameters) {
@@ -429,10 +428,10 @@ namespace Mono.CSharp
 
                                definition = gmd;
                        } else {
-                               definition = new ImportedParameterMemberDefinition (mb, returnType, parameters, this);
+                               definition = new ImportedMethodDefinition (mb, returnType, parameters, this);
                        }
 
-                       MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, mb, parameters, mod);
+                       MethodSpec ms = new MethodSpec (kind, declaringType, definition, returnType, parameters, mod);
                        if (tparams != null)
                                ms.IsGeneric = true;
 
@@ -510,7 +509,7 @@ namespace Mono.CSharp
                                                var ptype = types[i];
                                                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);
+                                                               default_value = Constant.CreateConstantFromValue (ptype, null, Location.Null);
                                                        } else {
                                                                default_value = ImportParameterConstant (value);
 
@@ -518,6 +517,21 @@ namespace Mono.CSharp
                                                                        default_value = new EnumConstant ((Constant) default_value, ptype);
                                                                }
                                                        }
+
+                                                       var attrs = CustomAttributeData.GetCustomAttributes (p);
+                                                       for (int ii = 0; ii < attrs.Count; ++ii) {
+                                                               var attr = attrs[ii];
+                                                               var dt = attr.Constructor.DeclaringType;
+                                                               if (dt.Namespace != CompilerServicesNamespace)
+                                                                       continue;
+
+                                                               if (dt.Name == "CallerLineNumberAttribute" && (ptype.BuiltinType == BuiltinTypeSpec.Type.Int || Convert.ImplicitNumericConversionExists (module.Compiler.BuiltinTypes.Int, ptype)))
+                                                                       mod |= Parameter.Modifier.CallerLineNumber;
+                                                               else if (dt.Name == "CallerFilePathAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype))
+                                                                       mod |= Parameter.Modifier.CallerFilePath;
+                                                               else if (dt.Name == "CallerMemberNameAttribute" && Convert.ImplicitReferenceConversionExists (module.Compiler.BuiltinTypes.String, ptype))
+                                                                       mod |= Parameter.Modifier.CallerMemberName;
+                                                       }
                                                } else if (value == Missing.Value) {
                                                        default_value = EmptyExpression.MissingValue;
                                                } else if (value == null) {
@@ -699,7 +713,7 @@ namespace Mono.CSharp
                        TypeSpec spec;
                        if (import_cache.TryGetValue (type, out spec)) {
                                if (spec.BuiltinType == BuiltinTypeSpec.Type.Object) {
-                                       if (dtype.IsDynamicObject (this))
+                                       if (dtype.IsDynamicObject ())
                                                return module.Compiler.BuiltinTypes.Dynamic;
 
                                        return spec;
@@ -708,7 +722,7 @@ namespace Mono.CSharp
                                if (!spec.IsGeneric || type.IsGenericTypeDefinition)
                                        return spec;
 
-                               if (!dtype.HasDynamicAttribute (this))
+                               if (!dtype.HasDynamicAttribute ())
                                        return spec;
 
                                // We've found same object in the cache but this one has a dynamic custom attribute
@@ -759,24 +773,34 @@ namespace Mono.CSharp
 
                                        for (int i = nested_hierarchy.Count; i != 0; --i) {
                                                var t = nested_hierarchy [i - 1];
-                                               spec = MemberCache.FindNestedType (spec, t.Name, t.Arity);
+                                               if (t.Kind == MemberKind.MissingType)
+                                                       spec = t;
+                                               else
+                                                       spec = MemberCache.FindNestedType (spec, t.Name, t.Arity);
+
                                                if (t.Arity > 0) {
                                                        spec = spec.MakeGenericType (module, targs.Skip (targs_pos).Take (spec.Arity).ToArray ());
                                                        targs_pos += t.Arity;
                                                }
                                        }
 
-                                       string name = type.Name;
-                                       int index = name.IndexOf ('`');
-                                       if (index > 0)
-                                               name = name.Substring (0, index);
+                                       if (spec.Kind == MemberKind.MissingType) {
+                                               spec = new TypeSpec (MemberKind.MissingType, spec, new ImportedTypeDefinition (type_def, this), type_def, Modifiers.PUBLIC);
+                                               spec.MemberCache = MemberCache.Empty;
+                                       } else {
+                                               if ((type_def.Attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate && IgnorePrivateMembers)
+                                                       return null;
 
-                                       spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos);
-                                       if (spec == null)
-                                               return null;
+                                               string name = type.Name;
+                                               int index = name.IndexOf ('`');
+                                               if (index > 0)
+                                                       name = name.Substring (0, index);
 
-                                       if (spec.Arity > 0) {
-                                               spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
+                                               spec = MemberCache.FindNestedType (spec, name, targs.Length - targs_pos);
+
+                                               if (spec.Arity > 0) {
+                                                       spec = spec.MakeGenericType (module, targs.Skip (targs_pos).ToArray ());
+                                               }
                                        }
                                }
 
@@ -832,9 +856,10 @@ namespace Mono.CSharp
 
                                if (kind == MemberKind.Class) {
                                        if ((ma & TypeAttributes.Sealed) != 0) {
-                                               mod |= Modifiers.SEALED;
                                                if ((ma & TypeAttributes.Abstract) != 0)
                                                        mod |= Modifiers.STATIC;
+                                               else
+                                                       mod |= Modifiers.SEALED;
                                        } else if ((ma & TypeAttributes.Abstract) != 0) {
                                                mod |= Modifiers.ABSTRACT;
                                        }
@@ -991,53 +1016,6 @@ namespace Mono.CSharp
                                spec.BaseType = base_type;
                        }
 
-                       MetaType[] ifaces;
-#if STATIC
-                       ifaces = type.__GetDeclaredInterfaces ();
-                       if (ifaces.Length != 0) {
-                               foreach (var iface in ifaces) {
-                                       var it = CreateType (iface);
-                                       if (it == null)
-                                               continue;
-
-                                       spec.AddInterface (it);
-
-                                       // Unfortunately not all languages expand inherited interfaces
-                                       var bifaces = it.Interfaces;
-                                       if (bifaces != null) {
-                                               foreach (var biface in bifaces) {
-                                                       spec.AddInterface (biface);
-                                               }
-                                       }
-                               }
-                       }
-
-                       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);
-                               }
-                       }
-#else
-                       ifaces = type.GetInterfaces ();
-
-                       if (ifaces.Length > 0) {
-                               foreach (var iface in ifaces) {
-                                       spec.AddInterface (CreateType (iface));
-                               }
-                       }
-#endif
-
                        if (spec.MemberDefinition.TypeParametersCount > 0) {
                                foreach (var tp in spec.MemberDefinition.TypeParameters) {
                                        ImportTypeParameterTypeConstraints (tp, tp.GetMetaInfo ());
@@ -1394,7 +1372,7 @@ namespace Mono.CSharp
                protected AttributesBag cattrs;
                protected readonly MetadataImporter importer;
 
-               public ImportedDefinition (MemberInfo provider, MetadataImporter importer)
+               protected ImportedDefinition (MemberInfo provider, MetadataImporter importer)
                {
                        this.provider = provider;
                        this.importer = importer;
@@ -1715,7 +1693,7 @@ namespace Mono.CSharp
        {
                readonly AParametersCollection parameters;
 
-               public ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
+               protected ImportedParameterMemberDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
                        : base (provider, type, importer)
                {
                        this.parameters = parameters;
@@ -1738,7 +1716,21 @@ namespace Mono.CSharp
                #endregion
        }
 
-       class ImportedGenericMethodDefinition : ImportedParameterMemberDefinition, IGenericMethodDefinition
+       class ImportedMethodDefinition : ImportedParameterMemberDefinition, IMethodDefinition
+       {
+               public ImportedMethodDefinition (MethodBase provider, TypeSpec type, AParametersCollection parameters, MetadataImporter importer)
+                       : base (provider, type, parameters, importer)
+               {
+               }
+
+               MethodBase IMethodDefinition.Metadata {
+                       get {
+                               return (MethodBase) provider;
+                       }
+               }
+       }
+
+       class ImportedGenericMethodDefinition : ImportedMethodDefinition, IGenericMethodDefinition
        {
                readonly TypeParameterSpec[] tparams;
 
@@ -1806,6 +1798,16 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+#if STATIC
+                               return ((MetaType) provider).__IsCyclicTypeForwarder;
+#else
+                               return false;
+#endif
+                       }
+               }
+
                public override string Name {
                        get {
                                if (name == null) {
@@ -1844,7 +1846,64 @@ namespace Mono.CSharp
 
                #endregion
 
-               public static void Error_MissingDependency (IMemberContext ctx, List<TypeSpec> types, Location loc)
+               public void DefineInterfaces (TypeSpec spec)
+               {
+                       var type = (MetaType) provider;
+                       MetaType[] ifaces;
+#if STATIC
+                       ifaces = type.__GetDeclaredInterfaces ();
+                       if (ifaces.Length != 0) {
+                               foreach (var iface in ifaces) {
+                                       var it = importer.CreateType (iface);
+                                       if (it == null)
+                                               continue;
+
+                                       spec.AddInterfaceDefined (it);
+
+                                       // Unfortunately not all languages expand inherited interfaces
+                                       var bifaces = it.Interfaces;
+                                       if (bifaces != null) {
+                                               foreach (var biface in bifaces) {
+                                                       spec.AddInterfaceDefined (biface);
+                                               }
+                                       }
+                               }
+                       }
+                       
+                       //
+                       // It's impossible to get declared interfaces only using System.Reflection
+                       // hence we need to mimic the behavior with ikvm-reflection too to keep
+                       // our type look-up logic same
+                       //
+                       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.AddInterfaceDefined (iface);
+                               }
+                       }
+#else
+                       ifaces = type.GetInterfaces ();
+
+                       if (ifaces.Length > 0) {
+                               foreach (var iface in ifaces) {
+                                       spec.AddInterface (importer.CreateType (iface));
+                               }
+                       }
+#endif
+
+               }
+
+               public static void Error_MissingDependency (IMemberContext ctx, List<MissingTypeSpecReference> missing, Location loc)
                {
                        // 
                        // Report details about missing type and most likely cause of the problem.
@@ -1852,33 +1911,44 @@ namespace Mono.CSharp
                        // or referenced from the user core in which case compilation error has to
                        // be reported because compiler cannot continue anyway
                        //
-                       for (int i = 0; i < types.Count; ++i) {
-                               var t = types [i];
+
+                       var report = ctx.Module.Compiler.Report;
+
+                       for (int i = 0; i < missing.Count; ++i) {
+                               var t = missing [i].Type;
 
                                //
-                               // Report missing types only once per type
+                               // Report missing types only once
                                //
-                               if (i > 0 && types.IndexOf (t) < i)
+                               if (report.Printer.MissingTypeReported (t.MemberDefinition))
                                        continue;
 
                                string name = t.GetSignatureForError ();
 
-                               if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
-                                       ctx.Module.Compiler.Report.Error (1683, loc,
+                               var caller = missing[i].Caller;
+                               if (caller.Kind != MemberKind.MissingType)
+                                       report.SymbolRelatedToPreviousError (caller);
+
+                               var definition = t.MemberDefinition;
+                               if (definition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
+                                       report.Error (1683, loc,
                                                "Reference to type `{0}' claims it is defined in this assembly, but it is not defined in source or any added modules",
                                                name);
-                               } else if (t.MemberDefinition.DeclaringAssembly.IsMissing) {
-                                       if (t.MemberDefinition.IsTypeForwarder) {
-                                               ctx.Module.Compiler.Report.Error (1070, loc,
+                               } else if (definition.DeclaringAssembly.IsMissing) {
+                                       if (definition.IsTypeForwarder) {
+                                               report.Error (1070, loc,
                                                        "The type `{0}' has been forwarded to an assembly that is not referenced. Consider adding a reference to assembly `{1}'",
-                                                       name, t.MemberDefinition.DeclaringAssembly.FullName);
+                                                       name, definition.DeclaringAssembly.FullName);
                                        } else {
-                                               ctx.Module.Compiler.Report.Error (12, loc,
+                                               report.Error (12, loc,
                                                        "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'",
-                                                       name, t.MemberDefinition.DeclaringAssembly.FullName);
+                                                       name, definition.DeclaringAssembly.FullName);
                                        }
+                               } else if (definition.IsTypeForwarder) {
+                                       report.Error (731, loc, "The type forwarder for type `{0}' in assembly `{1}' has circular dependency",
+                                               name, definition.DeclaringAssembly.FullName);
                                } else {
-                                       ctx.Module.Compiler.Report.Error (1684, loc,
+                                       report.Error (1684, loc,
                                                "Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found",
                                                name, t.MemberDefinition.DeclaringAssembly.FullName);
                                }
@@ -2055,7 +2125,13 @@ namespace Mono.CSharp
                                                if (get == null && set == null)
                                                        continue;
 
-                                               imported = importer.CreateProperty (p, declaringType, get, set);
+                                               try {
+                                                       imported = importer.CreateProperty (p, declaringType, get, set);
+                                               } catch (Exception ex) {
+                                                       throw new InternalErrorException (ex, "Could not import property `{0}' inside `{1}'",
+                                                               p.Name, declaringType.GetSignatureForError ());
+                                               }
+
                                                if (imported == null)
                                                        continue;
 
@@ -2169,6 +2245,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+                               return false;
+                       }
+               }
+
                public string Namespace {
                        get {
                                return null;