bool GenerateDebugNativeAssembly(bool skipJniAddNativeMethodRegistrationAttributeScan, List <TypeDefinition> javaTypes, TypeDefinitionCache cache, string outputDirectory, ApplicationConfigTaskState appConfState) { var javaToManaged = new List <TypeMapDebugEntry> (); var managedToJava = new List <TypeMapDebugEntry> (); var javaDuplicates = new Dictionary <string, List <TypeMapDebugEntry> > (StringComparer.Ordinal); foreach (TypeDefinition td in javaTypes) { UpdateApplicationConfig(td, appConfState); TypeMapDebugEntry entry = GetDebugEntry(td); HandleDebugDuplicates(javaDuplicates, entry, td, cache); javaToManaged.Add(entry); managedToJava.Add(entry); } SyncDebugDuplicates(javaDuplicates); var data = new ModuleDebugData { EntryCount = (uint)javaToManaged.Count, JavaToManagedMap = javaToManaged, ManagedToJavaMap = managedToJava, }; PrepareDebugMaps(data); GenerateNativeAssembly( (NativeAssemblerTargetProvider asmTargetProvider, bool sharedBitsWritten, bool sharedIncludeUsesAbiPrefix) => { return(new TypeMappingDebugNativeAssemblyGenerator(asmTargetProvider, data, outputDirectory, sharedBitsWritten, sharedIncludeUsesAbiPrefix)); } ); return(true); }
void SyncDebugDuplicates(Dictionary <string, List <TypeMapDebugEntry> > javaDuplicates) { foreach (List <TypeMapDebugEntry> duplicates in javaDuplicates.Values) { if (duplicates.Count < 2) { continue; } TypeMapDebugEntry template = duplicates [0]; for (int i = 1; i < duplicates.Count; i++) { duplicates[i].TypeDefinition = template.TypeDefinition; duplicates[i].ManagedName = template.ManagedName; } } }
void SyncDebugDuplicates(Dictionary <string, List <TypeMapDebugEntry> > javaDuplicates) { foreach (List <TypeMapDebugEntry> duplicates in javaDuplicates.Values) { if (duplicates.Count < 2) { continue; } // Java duplicates must all point to the same managed type // Managed types, however, must point back to the original Java type instead // File/assembly generator use the `DuplicateForJavaToManaged` field to know to which managed type the // duplicate Java type must be mapped. TypeMapDebugEntry template = duplicates [0]; for (int i = 1; i < duplicates.Count; i++) { duplicates[i].DuplicateForJavaToManaged = template; } } }
void HandleDebugDuplicates(Dictionary <string, List <TypeMapDebugEntry> > javaDuplicates, TypeMapDebugEntry entry, TypeDefinition td, TypeDefinitionCache cache) { List <TypeMapDebugEntry> duplicates; if (!javaDuplicates.TryGetValue(entry.JavaName, out duplicates)) { javaDuplicates.Add(entry.JavaName, new List <TypeMapDebugEntry> { entry }); } else { duplicates.Add(entry); TypeMapDebugEntry oldEntry = duplicates[0]; if (td.IsAbstract || td.IsInterface || oldEntry.TypeDefinition.IsAbstract || oldEntry.TypeDefinition.IsInterface) { if (td.IsAssignableFrom(oldEntry.TypeDefinition, cache)) { oldEntry.TypeDefinition = td; oldEntry.ManagedName = GetManagedTypeName(td); } } } }
bool GenerateDebugFiles(bool skipJniAddNativeMethodRegistrationAttributeScan, List <TypeDefinition> javaTypes, TypeDefinitionCache cache, string outputDirectory, ApplicationConfigTaskState appConfState) { var modules = new Dictionary <string, ModuleDebugData> (StringComparer.Ordinal); int maxModuleFileNameWidth = 0; int maxModuleNameWidth = 0; var javaDuplicates = new Dictionary <string, List <TypeMapDebugEntry> > (StringComparer.Ordinal); foreach (TypeDefinition td in javaTypes) { UpdateApplicationConfig(td, appConfState); string moduleName = td.Module.Assembly.Name.Name; ModuleDebugData module; if (!modules.TryGetValue(moduleName, out module)) { string outputFileName = $"{moduleName}{TypemapExtension}"; module = new ModuleDebugData { EntryCount = 0, JavaNameWidth = 0, ManagedNameWidth = 0, JavaToManagedMap = new List <TypeMapDebugEntry> (), ManagedToJavaMap = new List <TypeMapDebugEntry> (), OutputFilePath = Path.Combine(outputDirectory, outputFileName), ModuleName = moduleName, ModuleNameBytes = outputEncoding.GetBytes(moduleName), }; if (module.ModuleNameBytes.Length > maxModuleNameWidth) { maxModuleNameWidth = module.ModuleNameBytes.Length; } if (outputFileName.Length > maxModuleFileNameWidth) { maxModuleFileNameWidth = outputFileName.Length; } modules.Add(moduleName, module); } TypeMapDebugEntry entry = GetDebugEntry(td); HandleDebugDuplicates(javaDuplicates, entry, td, cache); if (entry.JavaName.Length > module.JavaNameWidth) { module.JavaNameWidth = (uint)entry.JavaName.Length + 1; } if (entry.ManagedName.Length > module.ManagedNameWidth) { module.ManagedNameWidth = (uint)entry.ManagedName.Length + 1; } module.JavaToManagedMap.Add(entry); module.ManagedToJavaMap.Add(entry); } SyncDebugDuplicates(javaDuplicates); foreach (ModuleDebugData module in modules.Values) { PrepareDebugMaps(module); } string typeMapIndexPath = Path.Combine(outputDirectory, "typemap.index"); using (var indexWriter = MemoryStreamPool.Shared.CreateBinaryWriter()) { OutputModules(modules, indexWriter, maxModuleFileNameWidth + 1); indexWriter.Flush(); Files.CopyIfStreamChanged(indexWriter.BaseStream, typeMapIndexPath); } GeneratedBinaryTypeMaps.Add(typeMapIndexPath); GenerateNativeAssembly( (NativeAssemblerTargetProvider asmTargetProvider, bool sharedBitsWritten, bool sharedIncludeUsesAbiPrefix) => { return(new TypeMappingDebugNativeAssemblyGenerator(asmTargetProvider, new ModuleDebugData(), outputDirectory, sharedBitsWritten)); } ); return(true); }