Merge pull request #3528 from BrzVlad/fix-sgen-check-before-collections
[mono.git] / mcs / mcs / ikvm.cs
index da6b0c11ab56b9ab6eda6b3123dff78bbf71082a..17dc6f8817627126ab4fcd9d4f39b3f1dcd9fd88 100644 (file)
@@ -220,6 +220,11 @@ namespace Mono.CSharp
                        return Builder.__AddModule (moduleFile);
                }
 
+               protected override List<AssemblyReferenceMessageInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
+               {
+                       return loader.GetNotUnifiedReferences (assemblyName);
+               }
+
                protected override void SaveModule (PortableExecutableKinds pekind, ImageFileMachine machine)
                {
                        module.Builder.__Save (pekind, machine);
@@ -233,13 +238,18 @@ namespace Mono.CSharp
                Assembly corlib;
                readonly List<Tuple<AssemblyName, string, Assembly>> loaded_names;
                static readonly Dictionary<string, string[]> sdk_directory;
+               Dictionary<AssemblyName, List<AssemblyReferenceMessageInfo>> resolved_version_mismatches;
+               static readonly TypeName objectTypeName = new TypeName ("System", "Object");
 
                static StaticLoader ()
                {
                        sdk_directory = new Dictionary<string, string[]> ();
-                       sdk_directory.Add ("2", new string[] { "2.0", "net_2_0", "v2.0.50727" });
-                       sdk_directory.Add ("4", new string[] { "4.0", "net_4_0", "v4.0.30319" });
-                       sdk_directory.Add ("4.5", new string[] { "4.5", "net_4_5", "v4.0.30319" });
+                       sdk_directory.Add ("2", new string[] { "2.0-api", "v2.0.50727" });
+                       sdk_directory.Add ("2.0", new string[] { "2.0-api", "v2.0.50727" });
+                       sdk_directory.Add ("4", new string[] { "4.0-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.0", new string[] { "4.0-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.5", new string[] { "4.5-api", "v4.0.30319" });
+                       sdk_directory.Add ("4.6", new string [] { "4.5", "net_4_x", "v4.0.30319" });
                }
 
                public StaticLoader (StaticImporter importer, CompilerContext compiler)
@@ -248,7 +258,7 @@ namespace Mono.CSharp
                        this.importer = importer;
                        domain = new Universe (UniverseOptions.MetadataOnly | UniverseOptions.ResolveMissingMembers | 
                                UniverseOptions.DisableFusion | UniverseOptions.DecodeVersionInfoAttributeBlobs |
-                               UniverseOptions.DeterministicOutput);
+                               UniverseOptions.DeterministicOutput | UniverseOptions.DisableDefaultAssembliesLookup);
                        
                        domain.AssemblyResolve += AssemblyReferenceResolver;
                        loaded_names = new List<Tuple<AssemblyName, string, Assembly>> ();
@@ -259,7 +269,7 @@ namespace Mono.CSharp
 
                                string sdk_path = null;
 
-                               string sdk_version = compiler.Settings.SdkVersion ?? "4.5";
+                               string sdk_version = compiler.Settings.SdkVersion ?? "4.6";
                                string[] sdk_sub_dirs;
 
                                if (!sdk_directory.TryGetValue (sdk_version, out sdk_sub_dirs))
@@ -349,27 +359,35 @@ namespace Mono.CSharp
                                if (version_mismatch is AssemblyBuilder)
                                        return version_mismatch;
 
-                               var v1 = new AssemblyName (refname).Version;
+                               var ref_an = new AssemblyName (refname);
+                               var v1 = ref_an.Version;
                                var v2 = version_mismatch.GetName ().Version;
 
                                if (v1 > v2) {
-//                                     compiler.Report.SymbolRelatedToPreviousError (args.RequestingAssembly.Location);
-                                       compiler.Report.Error (1705, "Assembly `{0}' references `{1}' which has a higher version number than imported assembly `{2}'",
-                                               args.RequestingAssembly.FullName, refname, version_mismatch.GetName ().FullName);
+                                       var messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
+                                               report.SymbolRelatedToPreviousError (args.RequestingAssembly.Location);
+                                               report.Error (1705, string.Format ("Assembly `{0}' depends on `{1}' which has a higher version number than referenced assembly `{2}'",
+                                                                                                                  args.RequestingAssembly.FullName, refname, version_mismatch.GetName ().FullName));
+                                       });
 
-                                       return domain.CreateMissingAssembly (args.Name);
+                                       AddReferenceVersionMismatch (args.RequestingAssembly.GetName (), messageInfo);
+                                       return version_mismatch;
                                }
 
                                if (!is_fx_assembly) {
-                                       if (v1.Major != v2.Major || v1.Minor != v2.Minor) {
-                                               compiler.Report.Warning (1701, 2,
-                                                       "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
-                                                       refname, version_mismatch.GetName ().FullName);
-                                       } else {
-                                               compiler.Report.Warning (1702, 3,
-                                                       "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
-                                                       refname, version_mismatch.GetName ().FullName);
-                                       }
+                                       var messageInfo = new AssemblyReferenceMessageInfo (ref_an, report => {
+                                               if (v1.Major != v2.Major || v1.Minor != v2.Minor) {
+                                                       report.Warning (1701, 2,
+                                                               "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
+                                                               refname, version_mismatch.GetName ().FullName);
+                                               } else {
+                                                       report.Warning (1702, 3,
+                                                               "Assuming assembly reference `{0}' matches assembly `{1}'. You may need to supply runtime policy",
+                                                               refname, version_mismatch.GetName ().FullName);
+                                               }
+                                       });
+
+                                       AddReferenceVersionMismatch (args.RequestingAssembly.GetName (), messageInfo);
                                }
 
                                return version_mismatch;
@@ -388,6 +406,20 @@ namespace Mono.CSharp
                        return domain.CreateMissingAssembly (args.Name);
                }
 
+               void AddReferenceVersionMismatch (AssemblyName an, AssemblyReferenceMessageInfo errorInfo)
+               {
+                       if (resolved_version_mismatches == null)
+                               resolved_version_mismatches = new Dictionary<AssemblyName, List<AssemblyReferenceMessageInfo>> ();
+
+                       List<AssemblyReferenceMessageInfo> names;
+                       if (!resolved_version_mismatches.TryGetValue (an, out names)) {
+                               names = new List<AssemblyReferenceMessageInfo> ();
+                               resolved_version_mismatches.Add (an, names);
+                       }
+
+                       names.Add (errorInfo);
+               }
+
                public void Dispose ()
                {
                        domain.Dispose ();
@@ -412,9 +444,27 @@ namespace Mono.CSharp
                        return default_references.ToArray ();
                }
 
-               public override bool HasObjectType (Assembly assembly)
+               public List<AssemblyReferenceMessageInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
                {
-                       return assembly.GetType (compiler.BuiltinTypes.Object.FullName) != null;
+                       List<AssemblyReferenceMessageInfo> list = null;
+                       if (resolved_version_mismatches != null)
+                               resolved_version_mismatches.TryGetValue (assemblyName, out list);
+
+                       return list;
+               }
+
+               public override Assembly HasObjectType (Assembly assembly)
+               {
+                       try {
+                               // System.Object can be forwarded and ikvm
+                               // transparently finds it in target assembly therefore
+                               // need to return actual obj assembly becauase in such
+                               // case it's different to assembly parameter
+                               var obj = assembly.FindType (objectTypeName);
+                               return obj == null ? null : obj.Assembly;
+                       } catch (Exception e) {
+                               throw new InternalErrorException (e, "Failed to load assembly `{0}'", assembly.FullName);
+                       }
                }
 
                public override Assembly LoadAssemblyFile (string fileName, bool isImplicitReference)
@@ -581,12 +631,30 @@ namespace Mono.CSharp
 
                public override void AddTypeForwarder (TypeSpec type, Location loc)
                {
-                       builder.__AddTypeForwarder (type.GetMetaInfo ());
+                       builder.__AddTypeForwarder (type.GetMetaInfo (), false);
                }
 
                public override void DefineWin32IconResource (string fileName)
                {
-                       builder.__DefineIconResource (File.ReadAllBytes (fileName));
+                       byte[] bytes;
+                       try {
+                               bytes = File.ReadAllBytes (fileName);
+                       } catch (Exception e) {
+                               ctx.Report.Error (7064, Location.Null, "Error opening icon file `{0}'. {1}", fileName, e.Message);
+                               return;
+                       }
+
+                       builder.__DefineIconResource (bytes);
+               }
+
+               public override AssemblyName[] GetReferencedAssemblies ()
+               {
+                       foreach (var m in builder.Modules) {
+                               if (m is ModuleBuilder)
+                                       return m.__GetReferencedAssemblies ();
+                       }
+
+                       return new AssemblyName [0];
                }
 
                public override void SetAlgorithmId (uint value, Location loc)