// Iterate over the modules.
for (int i = 0, nMetaModules = workspace.getNMetaModules(); i < nMetaModules; i++) {
MetaModule metaModule = workspace.getNthMetaModule(i);
// We're only interested in modules which are compiled.
ModuleTypeInfo moduleTypeInfo = metaModule.getTypeInfo();
if (moduleTypeInfo == null) {
// Not compiled.
continue;
}
int nImports = moduleTypeInfo.getNImportedModules();
// Iterate over the type constructors in the module.
int nTypeConstructors = moduleTypeInfo.getNTypeConstructors();
for (int j = 0; j < nTypeConstructors; j++) {
TypeConstructor typeCons = moduleTypeInfo.getNthTypeConstructor(j);
QualifiedName calName = typeCons.getName();
//Prelude.Unit and Prelude.Boolean are special cases in that they are algebraic types that however correspond
//to foreign types for the purposes of declaring foreign functions.
if (calName.equals(CAL_Prelude.TypeConstructors.Unit)) {
classToTypeConsNameMap.put(void.class, calName);
continue;
}
if (calName.equals(CAL_Prelude.TypeConstructors.Boolean)) {
classToTypeConsNameMap.put(boolean.class, calName);
continue;
}
// Check if the type is foreign.
ForeignTypeInfo fti = typeCons.getForeignTypeInfo();
if (fti != null && fti.getImplementationVisibility() == Scope.PUBLIC) {
Class<?> foreignType = fti.getForeignType();
// In cases where a single class maps to multiple type constructors,
// we choose the type in the module which is "closest" to the Prelude.
// For now, this distance is approximated by the number of imports in the module.
// TODOEL: Later, we can figure out the size of the import graph.
QualifiedName existingMappedName = classToTypeConsNameMap.get(foreignType);
if (existingMappedName == null) {
// Add a new mapping.
classToTypeConsNameMap.put(foreignType, calName);
continue;
}
// a mapping already exists.
ModuleTypeInfo existingMappingModuleTypeInfo = workspace.getMetaModule(existingMappedName.getModuleName()).getTypeInfo();
if (existingMappingModuleTypeInfo == null) {
// Existing mapping's type info not compiled.
continue;
}
int existingMappingNImports = existingMappingModuleTypeInfo.getNImportedModules();
if (nImports < existingMappingNImports) {
// override the existing mapping.
classToTypeConsNameMap.put(foreignType, calName);
continue;