diff --git a/Compiler/Compiler.cs b/Compiler/Compiler.cs index 8bc32800c..6867dedc3 100644 --- a/Compiler/Compiler.cs +++ b/Compiler/Compiler.cs @@ -3154,16 +3154,17 @@ namespace PascalABCCompiler var preloadedAssemblies = new List(); foreach (var reference in referenceDirectives) preloadedAssemblies.Add(PreloadReference(reference)); - - using (new NetHelper.AssemblyResolveScope(AppDomain.CurrentDomain, preloadedAssemblies)) - { - foreach (var reference in referenceDirectives) - CompileReference(res, reference); - } + + if (assemblyResolveScope == null) + assemblyResolveScope = new NetHelper.AssemblyResolveScope(AppDomain.CurrentDomain, preloadedAssemblies); + foreach (var reference in referenceDirectives) + CompileReference(res, reference); return res; } + NetHelper.AssemblyResolveScope assemblyResolveScope; + private bool IsPossibleNamespace(SyntaxTree.unit_or_namespace name_space, bool add_to_standard_modules, string curr_path) { if (name_space is SyntaxTree.uses_unit_in) @@ -4086,6 +4087,9 @@ namespace PascalABCCompiler project = null; StandarModules.Clear(); CompiledVariables.Clear(); + if (assemblyResolveScope != null) + assemblyResolveScope.Dispose(); + assemblyResolveScope = null; if (!close_pcu) { SyntaxTreeToSemanticTreeConverter = new TreeConverter.SyntaxTreeToSemanticTreeConverter(); diff --git a/TestSuite/libA.dll b/TestSuite/libA.dll new file mode 100644 index 000000000..961537c0b Binary files /dev/null and b/TestSuite/libA.dll differ diff --git a/TestSuite/libB.dll b/TestSuite/libB.dll new file mode 100644 index 000000000..89984d789 Binary files /dev/null and b/TestSuite/libB.dll differ diff --git a/TestSuite/libref.pas b/TestSuite/libref.pas new file mode 100644 index 000000000..470356dba --- /dev/null +++ b/TestSuite/libref.pas @@ -0,0 +1,5 @@ +{$reference 'libA.dll'} +begin + var t := new libA.ClassA(); + assert(t.field1 <> nil); +end. diff --git a/TreeConverter/NetWrappers/AssemblyResolveScope.cs b/TreeConverter/NetWrappers/AssemblyResolveScope.cs index 282dfeb3a..b2837d906 100644 --- a/TreeConverter/NetWrappers/AssemblyResolveScope.cs +++ b/TreeConverter/NetWrappers/AssemblyResolveScope.cs @@ -30,12 +30,29 @@ namespace PascalABCCompiler.NetHelper _appDomain.AssemblyResolve -= OnAssemblyResolve; } - private Assembly OnAssemblyResolve(object _, ResolveEventArgs args) + private Assembly OnAssemblyResolve(object obj, ResolveEventArgs args) { var requestedName = new AssemblyName(args.Name); if (_assemblies.TryGetValue(requestedName.Name, out var assembly)) return assembly; + var dir = PascalABCCompiler.NetHelper.NetHelper.GetAssemblyDirectory(args.RequestingAssembly); + if (string.IsNullOrEmpty(dir)) + return null; + string path = System.IO.Path.Combine(dir, args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll"); + if (System.IO.File.Exists(path)) + { + try + { + var assm = PascalABCCompiler.NetHelper.NetHelper.LoadAssembly(path, true); + _assemblies[assm.GetName().Name] = assm; + return assm; + } + catch + { + } + + } return null; } } diff --git a/TreeConverter/NetWrappers/NetHelper.cs b/TreeConverter/NetWrappers/NetHelper.cs index 8994b2042..b9463528c 100644 --- a/TreeConverter/NetWrappers/NetHelper.cs +++ b/TreeConverter/NetWrappers/NetHelper.cs @@ -342,12 +342,15 @@ namespace PascalABCCompiler.NetHelper cur_used_assemblies[typeof(string).Assembly] = typeof(string).Assembly; cur_used_assemblies[typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly] = typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly; type_search_cache.Clear(); + } private static Hashtable ass_name_cache; private static Hashtable file_dates; - - public static bool IsAssemblyChanged(string name) + private static Dictionary assm_full_paths; + + + public static bool IsAssemblyChanged(string name) { if (name == null) return false; Assembly a = ass_name_cache[name] as Assembly; @@ -430,6 +433,7 @@ namespace PascalABCCompiler.NetHelper a = System.Reflection.Assembly.LoadFrom(name); } ass_name_cache[name] = a; + assm_full_paths[a] = name; file_dates[a] = System.IO.File.GetLastWriteTime(name); return a; } @@ -884,6 +888,7 @@ namespace PascalABCCompiler.NetHelper compiled_pascal_types = new Hashtable(1024, StringComparer.CurrentCultureIgnoreCase); namespaces = new Hashtable(1024, StringComparer.CurrentCultureIgnoreCase); ass_name_cache = new Hashtable(1024, StringComparer.CurrentCultureIgnoreCase); + assm_full_paths = new Dictionary(); //ass_name_cache = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default); file_dates = new Hashtable(); //methods = new Hashtable(); @@ -935,6 +940,16 @@ namespace PascalABCCompiler.NetHelper AddToDictionaryMethod = typeof(Dictionary).GetMethod("Add"); } + public static string GetAssemblyDirectory(Assembly assm) + { + string path; + if (assm_full_paths.TryGetValue(assm, out path)) + { + return Path.GetDirectoryName(path); + } + return null; + } + private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { try