[Serialization] Differentiate module loading behavior for non-public imports

Differentiate `internal` and `fileprivate` imports from
implementation-only imports at the module-wide level to offer a
different module loading strategy. The main difference is for non-public
imports from a module with testing enabled to be loaded by transitive
clients.

Ideally, we would only load transitive non-public dependencies on
testable imports of the middle module. The current module loading logic
doesn't allow for this behavior easily as a module may be first loaded
for a normal import and extra dependencies would have to be loaded on
later imports. We may want to refactor the module loading logic to allow
this if needed.

rdar://106514965
This commit is contained in:
Alexis Laferrière
2023-03-15 22:09:31 -07:00
parent d7cd65cdd6
commit 599346885e
10 changed files with 91 additions and 20 deletions

View File

@@ -1021,6 +1021,8 @@ getActualImportControl(unsigned rawValue) {
return ModuleDecl::ImportFilterKind::Exported;
case static_cast<unsigned>(serialization::ImportControl::ImplementationOnly):
return ModuleDecl::ImportFilterKind::ImplementationOnly;
case static_cast<unsigned>(serialization::ImportControl::InternalOrBelow):
return ModuleDecl::ImportFilterKind::InternalOrBelow;
case static_cast<unsigned>(serialization::ImportControl::PackageOnly):
return ModuleDecl::ImportFilterKind::PackageOnly;
default:
@@ -1711,6 +1713,19 @@ ModuleFileSharedCore::getTransitiveLoadingBehavior(
}
}
if (dependency.isInternalOrBelow()) {
// Non-public imports are similar to implementation-only, the module
// loading behavior differs on loading those dependencies
// on testable imports.
if (isTestable() || !moduleIsResilient) {
return ModuleLoadingBehavior::Required;
} else if (debuggerMode) {
return ModuleLoadingBehavior::Optional;
} else {
return ModuleLoadingBehavior::Ignored;
}
}
if (dependency.isPackageOnly()) {
// Package dependencies are usually loaded only for import from the same
// package.