@@ -3,6 +3,7 @@ namespace DistIL.AsmIO;
3
3
using System . IO ;
4
4
using System . Reflection ;
5
5
using System . Reflection . PortableExecutable ;
6
+ using System . Text . RegularExpressions ;
6
7
7
8
public class ModuleResolver
8
9
{
@@ -25,7 +26,27 @@ public ModuleResolver(ICompilationLogger? logger = null)
25
26
26
27
public void AddSearchPaths ( IEnumerable < string > paths )
27
28
{
28
- _searchPaths = _searchPaths . Concat ( paths ) . Distinct ( StringComparer . OrdinalIgnoreCase ) . ToArray ( ) ;
29
+ _searchPaths = _searchPaths
30
+ . Concat ( paths )
31
+ . Select ( FixRuntimePackRefPath )
32
+ . Distinct ( StringComparer . OrdinalIgnoreCase )
33
+ . ToArray ( ) ;
34
+
35
+ //Try to change search path for the `NETCore.App.Ref` pack to the actual implementation path.
36
+ //This is done for a couple reasons:
37
+ // - We make the assumption that "System.Private.CoreLib" always exist, but it doesn't in ref packs.
38
+ // This would lead to multiple defs for e.g. "System.ValueType", which would cause issues.
39
+ // - We want to depend on _some_ private impl details which are not shipped in ref asms.
40
+ // Notably accessing private `List<T>` fields.
41
+ static string FixRuntimePackRefPath ( string path )
42
+ {
43
+ //e.g. "C:\Program Files\dotnet\packs\Microsoft.NETCore.App.Ref\7.0.3\ref\net7.0"
44
+ // shared **** ***********
45
+ //(I guess this piece will be in the top 3 reasons why I'll be sent to code hell.)
46
+ string normPath = Path . GetFullPath ( path ) . Replace ( '\\ ' , '/' ) ;
47
+ string implPath = Regex . Replace ( normPath , @"(.+?\/)packs(\/Microsoft\.NETCore\.App)\.Ref(\/.+?)\/.+" , "$1shared$2$3" ) ;
48
+ return implPath != normPath && Directory . Exists ( implPath ) ? implPath : path ;
49
+ }
29
50
}
30
51
31
52
public void AddTrustedSearchPaths ( )
0 commit comments