Ver código fonte

Refactor assemblies loading into a base class

Marek Safar 15 anos atrás
pai
commit
0296eeab1c
7 arquivos alterados com 151 adições e 145 exclusões
  1. 1 1
      mcs/errors/cs0006.cs
  2. 99 0
      mcs/mcs/assembly.cs
  3. 1 1
      mcs/mcs/attribute.cs
  4. 9 4
      mcs/mcs/driver.cs
  5. 1 1
      mcs/mcs/eval.cs
  6. 39 137
      mcs/mcs/reflection.cs
  7. 1 1
      mcs/mcs/rootcontext.cs

+ 1 - 1
mcs/errors/cs0006.cs

@@ -1,4 +1,4 @@
-// CS0006: cannot find metadata file `a:b'
+// CS0006: Metadata file `a:b' could not be found
 // Line: 0
 // Compiler options: -r:a:b
 

+ 99 - 0
mcs/mcs/assembly.cs

@@ -1031,4 +1031,103 @@ namespace Mono.CSharp
 			ctx.Report.RuntimeMissingSupport (Location.Null, "-target:module");
 		}
 	}
+
+	abstract class AssemblyReferencesLoader<T>
+	{
+		protected readonly CompilerContext compiler;
+
+		protected readonly List<string> paths;
+		readonly string[] default_references;
+
+		public AssemblyReferencesLoader (CompilerContext compiler)
+		{
+			this.compiler = compiler;
+
+			if (RootContext.LoadDefaultReferences)
+				default_references = GetDefaultReferences ();
+			else
+				default_references = new string[0];
+
+			paths = new List<string> ();
+			paths.AddRange (RootContext.ReferencesLookupPaths);
+			paths.Add (GetSystemDir ());
+			paths.Add (Directory.GetCurrentDirectory ());
+			// TODO: should remove redundant paths
+		}
+
+		public abstract bool HasObjectType (T assembly);
+		protected abstract string[] GetDefaultReferences ();
+		public abstract T LoadAssemblyFile (string fileName);
+		public abstract T LoadAssemblyDefault (string assembly);
+		public abstract void LoadReferences (ModuleContainer module);
+
+		protected void Error_FileNotFound (string fileName)
+		{
+			compiler.Report.Error (6, "Metadata file `{0}' could not be found", fileName);
+		}
+
+		protected void Error_FileCorrupted (string fileName)
+		{
+			compiler.Report.Error (9, "Metadata file `{0}' does not contain valid metadata", fileName);
+		}
+
+		//
+		// Returns the directory where the system assemblies are installed
+		//
+		static string GetSystemDir ()
+		{
+			return Path.GetDirectoryName (typeof (object).Assembly.Location);
+		}
+
+		protected void LoadReferencesCore (ModuleContainer module, out T corlib_assembly, out List<Tuple<RootNamespace, T>> loaded)
+		{
+			loaded = new List<Tuple<RootNamespace, T>> ();
+
+			//
+			// Load mscorlib.dll as the first
+			//
+			if (RootContext.StdLib) {
+				corlib_assembly = LoadAssemblyDefault ("mscorlib.dll");
+			} else {
+				corlib_assembly = default (T);
+			}
+
+			T a;
+			foreach (string r in default_references) {
+				a = LoadAssemblyDefault (r);
+				if (a != null)
+					loaded.Add (Tuple.Create (module.GlobalRootNamespace, a));
+			}
+
+			foreach (string r in RootContext.AssemblyReferences) {
+				a = LoadAssemblyFile (r);
+				if (a == null || EqualityComparer<T>.Default.Equals (a, corlib_assembly))
+					continue;
+
+				var key = Tuple.Create (module.GlobalRootNamespace, a);
+				if (loaded.Contains (key))
+					continue;
+
+				// A corlib assembly is the first assembly which contains System.Object
+				if (corlib_assembly == null && HasObjectType (a)) {
+					corlib_assembly = a;
+					continue;
+				}
+
+				loaded.Add (key);
+			}
+
+			foreach (var entry in RootContext.AssemblyReferencesAliases) {
+				a = LoadAssemblyFile (entry.Item2);
+				if (a == null)
+					continue;
+
+				var key = Tuple.Create (module.CreateRootNamespace (entry.Item1), a);
+				if (loaded.Contains (key))
+					continue;
+
+				loaded.Add (key);
+			}
+		}
+	}
 }

+ 1 - 1
mcs/mcs/attribute.cs

@@ -782,7 +782,7 @@ namespace Mono.CSharp {
 					}
 
 					if (orig_sec_assembly == null) {
-						string file = Path.Combine (orig_version_path, RootContext.OutputFile);
+						string file = Path.Combine (orig_version_path, Path.GetFileName (RootContext.OutputFile));
 						orig_sec_assembly = Assembly.LoadFile (file);
 					}
 

+ 9 - 4
mcs/mcs/driver.cs

@@ -1390,18 +1390,23 @@ namespace Mono.CSharp
 			// Quick hack
 			//
 			var output_file = RootContext.OutputFile;
-			if (output_file == null){
-				if (first_source == null){
+			string output_file_name;
+			if (output_file == null) {
+				if (first_source == null) {
 					Report.Error (1562, "If no source files are specified you must specify the output file with -out:");
 					return false;
 				}
-					
+
 				int pos = first_source.LastIndexOf ('.');
 
 				if (pos > 0)
 					output_file = first_source.Substring (0, pos) + RootContext.TargetExt;
 				else
 					output_file = first_source + RootContext.TargetExt;
+
+				output_file_name = output_file;
+			} else {
+				output_file_name = Path.GetFileName (output_file);
 			}
 
 			//
@@ -1410,7 +1415,7 @@ namespace Mono.CSharp
 			if (timestamps)
 				stopwatch = Stopwatch.StartNew ();
 
-			var assembly = module.MakeExecutable (output_file, output_file);
+			var assembly = module.MakeExecutable (output_file_name, output_file);
 
 			var importer = new ReflectionImporter (ctx.BuildinTypes);
 			assembly.Importer = importer;

+ 1 - 1
mcs/mcs/eval.cs

@@ -874,7 +874,7 @@ namespace Mono.CSharp {
 		static public void LoadAssembly (string file)
 		{
 			lock (evaluator_lock){
-				var a = loader.LoadAssemblyFile (file, false);
+				var a = loader.LoadAssemblyFile (file);
 				if (a != null)
 					loader.Importer.ImportAssembly (a, RootContext.ToplevelTypes.GlobalRootNamespace);
 			}

+ 39 - 137
mcs/mcs/reflection.cs

@@ -22,7 +22,6 @@ namespace Mono.CSharp
 	public class ReflectionImporter : MetadataImporter
 	{
 		public ReflectionImporter (BuildinTypes buildin)
-			: base ()
 		{
 			Initialize (buildin);
 		}
@@ -233,27 +232,17 @@ namespace Mono.CSharp
 		}
 	}
 
-	public class DynamicLoader
+	//
+	// Reflection based references loader
+	//
+	class DynamicLoader : AssemblyReferencesLoader<Assembly>
 	{
 		readonly ReflectionImporter importer;
-		readonly Report reporter;
-
-		// A list of default references, they can fail to load as the user didn't not specify them
-		string[] default_references;
-
-		List<string> paths;
 
 		public DynamicLoader (ReflectionImporter importer, CompilerContext compiler)
+			: base (compiler)
 		{
 			this.importer = importer;
-			this.reporter = compiler.Report;
-
-			default_references = GetDefaultReferences ();
-
-			paths = new List<string> ();
-			paths.AddRange (RootContext.ReferencesLookupPaths);
-			paths.Add (GetSystemDir ());
-			paths.Add (Directory.GetCurrentDirectory ());
 		}
 
 		public ReflectionImporter Importer {
@@ -262,67 +251,13 @@ namespace Mono.CSharp
 			}
 		}
 
-		void Error6 (string name, string log)
-		{
-			if (log != null && log.Length > 0)
-				reporter.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous ");
-			reporter.Error (6, "cannot find metadata file `{0}'", name);
-		}
-
-		void Error9 (string type, string filename, string log)
-		{
-			if (log != null && log.Length > 0)
-				reporter.ExtraInformation (Location.Null, "Log:\n" + log + "\n(log related to previous ");
-			reporter.Error (9, "file `{0}' has invalid `{1}' metadata", filename, type);
-		}
-
-		void BadAssembly (string filename, string log)
-		{
-/*
-			MethodInfo adder_method = null; // AssemblyDefinition.AddModule_Method;
-
-			if (adder_method != null) {
-				AssemblyName an = new AssemblyName ();
-				an.Name = ".temp";
-				var ab = AppDomain.CurrentDomain.DefineDynamicAssembly (an, AssemblyBuilderAccess.Run);
-				try {
-					object m = null;
-					try {
-						m = adder_method.Invoke (ab, new object [] { filename });
-					} catch (TargetInvocationException ex) {
-						throw ex.InnerException;
-					}
-
-					if (m != null) {
-						Report.Error (1509, "Referenced file `{0}' is not an assembly. Consider using `-addmodule' option instead",
-										Path.GetFileName (filename));
-						return;
-					}
-				} catch (FileNotFoundException) {
-					// did the file get deleted during compilation? who cares? swallow the exception
-				} catch (BadImageFormatException) {
-					// swallow exception
-				} catch (FileLoadException) {
-					// swallow exception
-				}
-			}
-*/
-			Error9 ("assembly", filename, log);
-		}
-
-		//
-		// Returns the directory where the system assemblies are installed
-		//
-		static string GetSystemDir ()
+		public override bool HasObjectType (Assembly assembly)
 		{
-			return Path.GetDirectoryName (typeof (object).Assembly.Location);
+			return assembly.GetType (compiler.BuildinTypes.Object.FullName) != null;
 		}
 
-		string[] GetDefaultReferences ()
+		protected override string[] GetDefaultReferences ()
 		{
-			if (!RootContext.LoadDefaultReferences)
-				return new string [0];
-
 			//
 			// For now the "default config" is harcoded into the compiler
 			// we can move this outside later
@@ -345,7 +280,12 @@ namespace Mono.CSharp
 			return default_references.ToArray ();
 		}
 
-		public Assembly LoadAssemblyFile (string assembly, bool soft)
+		public override Assembly LoadAssemblyFile (string fileName)
+		{
+			return LoadAssemblyFile (fileName, false);
+		}
+
+		Assembly LoadAssemblyFile (string assembly, bool soft)
 		{
 			Assembly a = null;
 			string total_log = "";
@@ -380,21 +320,22 @@ namespace Mono.CSharp
 						}
 					}
 					if (err) {
-						Error6 (assembly, total_log);
+						Error_FileNotFound (assembly);
 						return a;
 					}
 				}
-			} catch (BadImageFormatException f) {
-				// .NET 2.0 throws this if we try to load a module without an assembly manifest ...
-				BadAssembly (f.FileName, f.FusionLog);
-			} catch (FileLoadException f) {
-				// ... while .NET 1.1 throws this
-				BadAssembly (f.FileName, f.FusionLog);
+			} catch (BadImageFormatException) {
+				Error_FileCorrupted (assembly);
 			}
 
 			return a;
 		}
 
+		public override Assembly LoadAssemblyDefault (string fileName)
+		{
+			return LoadAssemblyFile (fileName, true);
+		}
+
 		void LoadModule (AssemblyDefinition assembly, string module)
 		{
 			string total_log = "";
@@ -418,76 +359,37 @@ namespace Mono.CSharp
 						}
 					}
 					if (err) {
-						Error6 (module, total_log);
+						Error_FileNotFound (module);
 						return;
 					}
 				}
-			} catch (BadImageFormatException f) {
-				Error9 ("module", f.FileName, f.FusionLog);
-			} catch (FileLoadException f) {
-				Error9 ("module", f.FileName, f.FusionLog);
+			} catch (BadImageFormatException) {
+				Error_FileCorrupted (module);
 			}
 		}
 
-		/// <summary>
-		///   Loads all assemblies referenced on the command line
-		/// </summary>
-		public void LoadReferences (ModuleContainer module)
+		public void LoadModules (AssemblyDefinition assembly)
 		{
-			Assembly a;
-			var loaded = new List<Tuple<RootNamespace, Assembly>> ();
-
-			//
-			// Load Core Library for default compilation
-			//
-			if (RootContext.StdLib) {
-				a = LoadAssemblyFile ("mscorlib", false);
-				if (a != null)
-					loaded.Add (Tuple.Create (module.GlobalRootNamespace, a));
-			}
-
-			foreach (string r in default_references) {
-				a = LoadAssemblyFile (r, true);
-				if (a != null)
-					loaded.Add (Tuple.Create (module.GlobalRootNamespace, a));
-			}
-
-			foreach (string r in RootContext.AssemblyReferences) {
-				a = LoadAssemblyFile (r, false);
-				if (a == null)
-					continue;
-
-				var key = Tuple.Create (module.GlobalRootNamespace, a);
-				if (loaded.Contains (key))
-					continue;
-
-				loaded.Add (key);
-			}
-
-			foreach (var entry in RootContext.AssemblyReferencesAliases) {
-				a = LoadAssemblyFile (entry.Item2, false);
-				if (a == null)
-					continue;
-
-				var key = Tuple.Create (module.CreateRootNamespace (entry.Item1), a);
-				if (loaded.Contains (key))
-					continue;
-
-				loaded.Add (key);
-			}
+			if (RootContext.Modules.Count == 0)
+				return;
 
-			foreach (var entry in loaded) {
-				importer.ImportAssembly (entry.Item2, entry.Item1);
+			foreach (var module in RootContext.Modules) {
+				LoadModule (assembly, module);
 			}
 		}
 
-		public void LoadModules (AssemblyDefinition assembly)
+		public override void LoadReferences (ModuleContainer module)
 		{
-			if (RootContext.Modules.Count == 0)
+			Assembly corlib;
+			List<Tuple<RootNamespace, Assembly>> loaded;
+			base.LoadReferencesCore (module, out corlib, out loaded);
+
+			if (corlib == null)
 				return;
 
-			foreach (var module in RootContext.Modules) {
-				LoadModule (assembly, module);
+			importer.ImportAssembly (corlib, module.GlobalRootNamespace);
+			foreach (var entry in loaded) {
+				importer.ImportAssembly (entry.Item2, entry.Item1);
 			}
 		}
 	}

+ 1 - 1
mcs/mcs/rootcontext.cs

@@ -110,7 +110,7 @@ namespace Mono.CSharp {
 				output_file = value;
 			}
 			get {
-				return Path.GetFileName (output_file);
+				return output_file;
 			}
 		}