Merge branch 'master' into msbuilddll2
[mono.git] / mcs / mcs / import.cs
index f7d452b05c04fd1bda48cd802a6f3737ef76142b..125404f6d920693b7289b968bde5a15fae1ff9c1 100644 (file)
@@ -6,7 +6,7 @@
 // Dual licensed under the terms of the MIT X11 or GNU GPL
 //
 // Copyright 2009-2011 Novell, Inc
-// Copyright 2011-2013 Xamarin, Inc (http://www.xamarin.com)
+// Copyright 2011-2012 Xamarin, Inc (http://www.xamarin.com)
 //
 
 using System;
@@ -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) {
@@ -123,7 +123,6 @@ namespace Mono.CSharp
                protected readonly ModuleContainer module;
 
                public static readonly string CompilerServicesNamespace = "System.Runtime.CompilerServices";
-               public static readonly string PlayScriptCompilerNamespace = "PlayScript.Runtime.CompilerServices";
 
                protected MetadataImporter (ModuleContainer module)
                {
@@ -153,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:
@@ -205,16 +204,6 @@ namespace Mono.CSharp
                                                return new ConstSpec (declaringType, definition, field_type, fi, mod, dc);
                                }
 
-                               if (field_type == module.PlayscriptTypes.Namespace.TypeSpec) {
-                                       var attributes = CustomAttributeData.GetCustomAttributes (fi);
-
-                                       var data = FindAttribute (attributes, "NamespaceFieldAttribute", PlayScriptCompilerNamespace);
-                                       if (data != null) {
-                                               string value = data.ConstructorArguments[0].Value as string;
-                                               return new PlayScript.NamespaceFieldSpec (declaringType, definition, field_type, fi, mod, value);
-                                       }
-                               }
-
                                mod |= Modifiers.READONLY;
                        } else {
                                var req_mod = fi.GetRequiredCustomModifiers ();
@@ -335,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);
                                        }
                                }
@@ -509,15 +497,10 @@ namespace Mono.CSharp
                                } else {
                                        types[i] = ImportType (p.ParameterType, new DynamicTypeReader (p));
 
-                                       if (i >= pi.Length - 2) {
-                                               var ti = types[i];
-
-                                               if (ti is ArrayContainer && HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) {
+                                       if (i >= pi.Length - 2 && types[i] is ArrayContainer) {
+                                               if (HasAttribute (CustomAttributeData.GetCustomAttributes (p), "ParamArrayAttribute", "System")) {
                                                        mod = Parameter.Modifier.PARAMS;
                                                        is_params = true;
-                                               } else if (ti == module.PlayscriptTypes.Array.TypeSpec && HasAttribute (CustomAttributeData.GetCustomAttributes (p), "RestArrayParameterAttribute", PlayScriptCompilerNamespace)) {
-                                                       mod = Parameter.Modifier.RestArray;
-                                                       is_params = true;
                                                }
                                        }
 
@@ -650,24 +633,7 @@ namespace Mono.CSharp
                        }
 
                        PropertySpec spec = null;
-                       ImportedMemberDefinition imd = new ImportedMemberDefinition (pi, type, this);
-
-                       if (param.IsEmpty) {
-                               if (get != null && set == null && declaringType.MemberDefinition.IsPlayScriptType) {
-                                       var attributes = CustomAttributeData.GetCustomAttributes (pi);
-
-                                       var data = FindAttribute (attributes, "ConstantFieldAttribute", PlayScriptCompilerNamespace);
-                                       if (data != null) {
-                                               var pc = new PlayScript.ImportedPropertyConstant (pi, type, this);
-                                               if (data.ConstructorArguments.Count == 1) {
-                                                       pc.Initializer = Constant.CreateConstantFromValue (type,
-                                                               data.ConstructorArguments[0].Value, Location.Null);
-                                               }
-
-                                               imd = pc;
-                                       }
-                               }
-                       } else {
+                       if (!param.IsEmpty) {
                                if (is_valid_property) {
                                        var index_name = declaringType.MemberDefinition.GetAttributeDefaultMember ();
                                        if (index_name == null) {
@@ -706,7 +672,7 @@ namespace Mono.CSharp
                        }
 
                        if (spec == null)
-                               spec = new PropertySpec (MemberKind.Property, declaringType, imd, type, pi, mod);
+                               spec = new PropertySpec (MemberKind.Property, declaringType, new ImportedMemberDefinition (pi, type, this), type, pi, mod);
 
                        if (!is_valid_property) {
                                spec.IsNotCSharpCompatible = true;
@@ -747,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;
@@ -756,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
@@ -890,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;
                                        }
@@ -932,21 +899,8 @@ namespace Mono.CSharp
                                        bts.SetDefinition (definition, type, mod);
                        }
 
-                       if (spec == null) {
-                               if (kind == MemberKind.Class && declaringType == null) {
-                                       var attributes = CustomAttributeData.GetCustomAttributes (type);
-                                       // TODO: Add assembly level attribute to speed this up?
-
-                                       if (HasAttribute (attributes, "DynamicClassAttribute", PlayScriptCompilerNamespace)) {
-                                               definition.IsPlayScriptType = true;
-                                               mod |= Modifiers.DYNAMIC;
-                                       } else if (HasAttribute (attributes, "PlayScriptAttribute", PlayScriptCompilerNamespace)) {
-                                               definition.IsPlayScriptType = true;
-                                       }
-                               }
-
+                       if (spec == null)
                                spec = new TypeSpec (kind, declaringType, definition, type, mod);
-                       }
 
                        import_cache.Add (type, spec);
 
@@ -1035,22 +989,17 @@ namespace Mono.CSharp
                // they can be assembly specific therefore we do check based on names only
                //
                public static bool HasAttribute (IList<CustomAttributeData> attributesData, string attrName, string attrNamespace)
-               {
-                       return FindAttribute (attributesData, attrName, attrNamespace) != null;
-               }
-
-               static CustomAttributeData FindAttribute (IList<CustomAttributeData> attributesData, string attrName, string attrNamespace)
                {
                        if (attributesData.Count == 0)
-                               return null;
+                               return false;
 
                        foreach (var attr in attributesData) {
                                var dt = attr.Constructor.DeclaringType;
                                if (dt.Name == attrName && dt.Namespace == attrNamespace)
-                                       return attr;
+                                       return true;
                        }
 
-                       return null;
+                       return false;
                }
 
                void ImportTypeBase (TypeSpec spec, MetaType type)
@@ -1064,9 +1013,6 @@ namespace Mono.CSharp
                                else
                                        base_type = CreateType (type.BaseType);
 
-                               if (base_type == null && spec.MemberDefinition.IsPlayScriptType)
-                                       base_type = module.PlayscriptTypes.Object;
-
                                spec.BaseType = base_type;
                        }
 
@@ -1426,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;
@@ -1852,7 +1798,15 @@ namespace Mono.CSharp
                        }
                }
 
-               public bool IsPlayScriptType { get; set; }
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+#if STATIC
+                               return ((MetaType) provider).__IsCyclicTypeForwarder;
+#else
+                               return false;
+#endif
+                       }
+               }
 
                public override string Name {
                        get {
@@ -1949,7 +1903,7 @@ namespace Mono.CSharp
 
                }
 
-               public static void Error_MissingDependency (IMemberContext ctx, List<TypeSpec> types, Location loc)
+               public static void Error_MissingDependency (IMemberContext ctx, List<MissingTypeSpecReference> missing, Location loc)
                {
                        // 
                        // Report details about missing type and most likely cause of the problem.
@@ -1960,8 +1914,8 @@ namespace Mono.CSharp
 
                        var report = ctx.Module.Compiler.Report;
 
-                       for (int i = 0; i < types.Count; ++i) {
-                               var t = types [i];
+                       for (int i = 0; i < missing.Count; ++i) {
+                               var t = missing [i].Type;
 
                                //
                                // Report missing types only once
@@ -1971,20 +1925,28 @@ namespace Mono.CSharp
 
                                string name = t.GetSignatureForError ();
 
-                               if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
+                               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) {
+                               } 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 {
                                                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 {
                                        report.Error (1684, loc,
                                                "Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found",
@@ -2163,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;
 
@@ -2277,7 +2245,7 @@ namespace Mono.CSharp
                        }
                }
 
-               bool ITypeDefinition.IsPlayScriptType {
+               bool ITypeDefinition.IsCyclicTypeForwarder {
                        get {
                                return false;
                        }