45 readonly ConcurrentDictionary<string, Type> runtimeTypeCache =
new();
48 internal Universe universe;
49 internal Assembly runtimeAssembly;
50 internal Assembly baseAssembly;
52 internal int errorCount;
54 internal Universe Universe => universe;
62 this.diagnostics = diagnostics ??
throw new ArgumentNullException(nameof(diagnostics));
72 internal void Init(
bool nonDeterministicOutput,
DebugMode debug, IList<string> libpaths)
74 var options = UniverseOptions.ResolveMissingMembers | UniverseOptions.EnableFunctionPointers;
75 if (nonDeterministicOutput ==
false)
76 options |= UniverseOptions.DeterministicOutput;
79 var coreLibName = FindCoreLibName(rootTarget.unresolvedReferences, libpaths);
80 if (coreLibName ==
null)
82 diagnostics.CoreClassesMissing();
83 throw new Exception();
86 universe =
new Universe(options, coreLibName);
87 universe.ResolvedMissingMember += ResolvedMissingMember;
91 universe.SetSymbolWriterFactory(module =>
new PortablePdbSymbolWriter(module));
100 static string FindCoreLibName(IList<string> references, IList<string> libpaths)
102 if (references !=
null)
103 foreach (var reference
in references)
104 if (GetAssemblyNameIfCoreLib(reference) is
string coreLibName)
107 if (libpaths !=
null)
108 foreach (var libpath
in libpaths)
109 foreach (var dll
in Directory.GetFiles(libpath,
"*.dll"))
110 if (GetAssemblyNameIfCoreLib(dll) is
string coreLibName)
121 static string GetAssemblyNameIfCoreLib(
string path)
123 if (File.Exists(path) ==
false)
128 using var st = File.OpenRead(path);
129 using var pe =
new PEReader(st);
130 var mr = pe.GetMetadataReader();
132 foreach (var handle
in mr.TypeDefinitions)
133 if (IsSystemObject(mr, handle))
134 return mr.GetString(mr.GetAssemblyDefinition().Name);
138 catch (
System.BadImageFormatException)
142 catch (InvalidOperationException)
158 static bool IsSystemObject(MetadataReader reader, TypeDefinitionHandle th)
160 var td = reader.GetTypeDefinition(th);
161 var ns = reader.GetString(td.Namespace);
162 var nm = reader.GetString(td.Name);
164 return ns ==
"System" && nm ==
"Object";
167 void ResolvedMissingMember(Module requestingModule, MemberInfo member)
169 if (requestingModule !=
null && member is Type)
171 diagnostics.UnableToResolveType(requestingModule.Name, ((Type)member).FullName, member.Module.FullyQualifiedName);
175 internal Assembly
Load(
string assemblyString)
177 var
asm = universe.Load(assemblyString);
179 throw new FileNotFoundException(assemblyString);
184 internal Assembly LoadFile(
string path)
186 return universe.LoadFile(path);
189 internal Type GetRuntimeType(
string name)
191 return runtimeTypeCache.GetOrAdd(name, runtimeAssembly.GetType);
206 var fw = GetClassForMapXml(loader, clazz).GetFieldWrapper(name, sig);
216 var ccl = (ImportClassLoader)loader;
217 return ccl.GetTypeFromReferencedAssembly(name);
220 internal static void LinkageError(
string msg, RuntimeJavaType actualType, RuntimeJavaType expectedType, params
object[] values)
222 object[] args =
new object[values.Length + 2];
223 values.CopyTo(args, 2);
224 args[0] = AssemblyQualifiedName(actualType);
225 args[1] = AssemblyQualifiedName(expectedType);
226 string str =
string.Format(msg, args);
229 str +=
string.Format(
"\n\t(Please add a reference to {0})", expectedType.TypeAsBaseType.Assembly.Location);
235 static string AssemblyQualifiedName(RuntimeJavaType javaType)
237 var loader = javaType.ClassLoader;
238 var acl = loader as RuntimeAssemblyClassLoader;
240 return javaType.Name +
", " + acl.GetAssembly(javaType).FullName;
242 var ccl = loader as ImportClassLoader;
244 return javaType.Name +
", " + ccl.GetTypeWrapperFactory().ModuleBuilder.Assembly.FullName;
246 return javaType.Name +
" (unknown assembly)";
249 internal void IssueMissingTypeMessage(Type type)
252 if (type.Assembly.__IsMissing)
253 diagnostics.MissingReference(type.FullName, type.Assembly.FullName);
255 diagnostics.MissingType(type.FullName, type.Assembly.FullName);
258 internal void SuppressWarning(ImportState options,
Diagnostic diagnostic,
string name)
260 options.suppressWarnings.Add($
"{diagnostic.Id}:{name}");