mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
AST: Fold forAllImportedModules() into collectLinkLibraries()
This commit is contained in:
@@ -1375,62 +1375,6 @@ bool ModuleDecl::registerEntryPointFile(FileUnit *file, SourceLoc diagLoc,
|
||||
return true;
|
||||
}
|
||||
|
||||
template<bool respectVisibility>
|
||||
static bool
|
||||
forAllImportedModules(const ModuleDecl *topLevel,
|
||||
ModuleDecl::AccessPathTy thisPath,
|
||||
llvm::function_ref<bool(ModuleDecl::ImportedModule)> fn) {
|
||||
using ImportedModule = ModuleDecl::ImportedModule;
|
||||
using AccessPathTy = ModuleDecl::AccessPathTy;
|
||||
|
||||
llvm::SmallSet<ImportedModule, 32, ModuleDecl::OrderImportedModules> visited;
|
||||
SmallVector<ImportedModule, 32> stack;
|
||||
|
||||
ModuleDecl::ImportFilter filter = ModuleDecl::ImportFilterKind::Public;
|
||||
if (!respectVisibility)
|
||||
filter |= ModuleDecl::ImportFilterKind::Private;
|
||||
|
||||
ModuleDecl::ImportFilter topLevelFilter = filter;
|
||||
if (!respectVisibility)
|
||||
topLevelFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
|
||||
topLevel->getImportedModules(stack, topLevelFilter);
|
||||
|
||||
// Make sure the top-level module is first; we want pre-order-ish traversal.
|
||||
AccessPathTy overridingPath;
|
||||
if (respectVisibility)
|
||||
overridingPath = thisPath;
|
||||
stack.emplace_back(overridingPath, const_cast<ModuleDecl *>(topLevel));
|
||||
|
||||
while (!stack.empty()) {
|
||||
auto next = stack.pop_back_val();
|
||||
|
||||
// Filter any whole-module imports, and skip specific-decl imports if the
|
||||
// import path doesn't match exactly.
|
||||
if (next.first.empty() || !respectVisibility)
|
||||
next.first = overridingPath;
|
||||
else if (!overridingPath.empty() &&
|
||||
!ModuleDecl::isSameAccessPath(next.first, overridingPath)) {
|
||||
// If we ever allow importing non-top-level decls, it's possible the rule
|
||||
// above isn't what we want.
|
||||
assert(next.first.size() == 1 && "import of non-top-level decl");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!visited.insert(next).second)
|
||||
continue;
|
||||
|
||||
if (!fn(next))
|
||||
return false;
|
||||
|
||||
if (respectVisibility)
|
||||
next.second->getImportedModulesForLookup(stack);
|
||||
else
|
||||
next.second->getImportedModules(stack, filter);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void ModuleDecl::collectLinkLibraries(LinkLibraryCallback callback) const {
|
||||
// FIXME: The proper way to do this depends on the decls used.
|
||||
FORWARD(collectLinkLibraries, (callback));
|
||||
@@ -1438,21 +1382,40 @@ void ModuleDecl::collectLinkLibraries(LinkLibraryCallback callback) const {
|
||||
|
||||
void
|
||||
SourceFile::collectLinkLibraries(ModuleDecl::LinkLibraryCallback callback) const {
|
||||
forAllImportedModules<false>(getParentModule(), /*thisPath*/{},
|
||||
[=](ModuleDecl::ImportedModule import) -> bool {
|
||||
swift::ModuleDecl *next = import.second;
|
||||
if (next->getName() == getParentModule()->getName())
|
||||
return true;
|
||||
llvm::SmallDenseSet<ModuleDecl *, 32> visited;
|
||||
SmallVector<ModuleDecl::ImportedModule, 32> stack;
|
||||
|
||||
// Hack: Assume other REPL files already have their libraries linked.
|
||||
if (!next->getFiles().empty())
|
||||
if (auto *nextSource = dyn_cast<SourceFile>(next->getFiles().front()))
|
||||
if (nextSource->Kind == SourceFileKind::REPL)
|
||||
return true;
|
||||
ModuleDecl::ImportFilter filter = ModuleDecl::ImportFilterKind::Public;
|
||||
filter |= ModuleDecl::ImportFilterKind::Private;
|
||||
|
||||
next->collectLinkLibraries(callback);
|
||||
return true;
|
||||
});
|
||||
auto *topLevel = getParentModule();
|
||||
|
||||
ModuleDecl::ImportFilter topLevelFilter = filter;
|
||||
topLevelFilter |= ModuleDecl::ImportFilterKind::ImplementationOnly;
|
||||
topLevel->getImportedModules(stack, topLevelFilter);
|
||||
|
||||
// Make sure the top-level module is first; we want pre-order-ish traversal.
|
||||
stack.emplace_back(ModuleDecl::AccessPathTy(),
|
||||
const_cast<ModuleDecl *>(topLevel));
|
||||
|
||||
while (!stack.empty()) {
|
||||
auto next = stack.pop_back_val().second;
|
||||
|
||||
if (!visited.insert(next).second)
|
||||
continue;
|
||||
|
||||
if (next->getName() != getParentModule()->getName()) {
|
||||
// Hack: Assume other REPL files already have their libraries linked.
|
||||
if (!next->getFiles().empty())
|
||||
if (auto *nextSource = dyn_cast<SourceFile>(next->getFiles().front()))
|
||||
if (nextSource->Kind == SourceFileKind::REPL)
|
||||
continue;
|
||||
|
||||
next->collectLinkLibraries(callback);
|
||||
}
|
||||
|
||||
next->getImportedModules(stack, filter);
|
||||
}
|
||||
}
|
||||
|
||||
bool ModuleDecl::walk(ASTWalker &Walker) {
|
||||
|
||||
Reference in New Issue
Block a user