The service `ModuleFile::getImportedModules` is called after the
dependency loading logic runs. We can trust this previous logic to have
correctly loaded optional dependencies. In `getImportedModules` we can
just ignore such missing dependencies.
rdar://115372249
* A multi-file scenario where one file has a normal import and the other
a testable import. In this case we still load the extra dependencies
and show diagnostics only of the testable import.
* A scenario where module A @testable imports module B, which @_exported
imports module C. In this case, non-public imports of B are loaded,
but not those of C. This is a limitation of the current implementation
and could be improved upon in the future.
A @testable import allows a client to call internal decls which may
refer to non-public dependencies. To support such a use case, load
non-public transitive dependencies of a module when it's imported
@testable from the main module.
This replaces the previous behavior where we loaded those dependencies
for any modules built for testing. This was risky as we would load more
module for any debug build, opening the door to a different behavior
between debug and release builds. In contrast, applying this logic to
@testable clients will only change the behavior of test targets.
rdar://107329303
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 general test applies to all access-level. Let's precise that it
tests the scenario where a client is outside of the package to preserve
the current behavior. A new tests will check the behavior of a package
dependency for clients in package.
When using access level on imports, consider non-public imports to be
implementation details not exposed to clients. As such, a client loading
a library doesn't need to load non-public transitive dependencies.
This behave like `@_implementationOnly imports` at a module-wide level,
but it is restricted to resilient modules only. An import with any
access-level in a non-resilient module remains visible to transitive
clients.