Cache only resolved types not expression to report correct error location. Fixes...
[mono.git] / mcs / mcs / import.cs
index ce43902012d843e19be99e0355e1ece5da5246d9..72538a2da18ecf16cded87dfe6ee278b9feffbfa 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:
@@ -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;
 
@@ -714,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;
@@ -723,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
@@ -774,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 ());
+                                               }
                                        }
                                }
 
@@ -847,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;
                                        }
@@ -1362,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;
@@ -1683,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;
@@ -1706,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;
 
@@ -1869,7 +1893,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.
@@ -1877,33 +1901,40 @@ 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 ();
 
+                               var caller = missing[i].Caller;
+                               if (caller.Kind != MemberKind.MissingType)
+                                       report.SymbolRelatedToPreviousError (caller);
+
                                if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
-                                       ctx.Module.Compiler.Report.Error (1683, loc,
+                                       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,
+                                               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);
                                        } 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);
                                        }
                                } 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);
                                }
@@ -2080,7 +2111,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;