This commit is contained in:
Ivan Bondarev 2023-07-30 14:54:49 +02:00
parent 7f6030c253
commit 8660c5634c
6 changed files with 50 additions and 9 deletions

View file

@ -3154,16 +3154,17 @@ namespace PascalABCCompiler
var preloadedAssemblies = new List<Assembly>();
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();

BIN
TestSuite/libA.dll Normal file

Binary file not shown.

BIN
TestSuite/libB.dll Normal file

Binary file not shown.

5
TestSuite/libref.pas Normal file
View file

@ -0,0 +1,5 @@
{$reference 'libA.dll'}
begin
var t := new libA.ClassA();
assert(t.field1 <> nil);
end.

View file

@ -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;
}
}

View file

@ -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<Assembly, string> 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<Assembly, string>();
//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<string, object>).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