Skip to content

Commit a7e1cb3

Browse files
author
Nathan Hawes
committed
[SourceKit] Update cursor info to report symbols from cross-import overlays as coming from the underylying module.
Also refactor some of the interface generation cross-import support code to be shared.
1 parent b3f296d commit a7e1cb3

15 files changed

+417
-339
lines changed

Diff for: include/swift/AST/Module.h

+25
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,31 @@ class ModuleDecl : public DeclContext, public TypeDecl {
335335
void getDeclaredCrossImportBystanders(
336336
SmallVectorImpl<Identifier> &bystanderNames);
337337

338+
/// A lazily populated mapping from each declared cross import overlay this
339+
/// module transitively underlies to its bystander and immediate underlying
340+
/// module.
341+
llvm::SmallDenseMap<ModuleDecl *, std::pair<Identifier, ModuleDecl *>, 1>
342+
declaredCrossImportsTransitive;
343+
344+
/// Determines if the given \p overlay is a declarared cross-import overlay of
345+
/// this module, or an of its transitively declared overlay modules.
346+
///
347+
/// This is used by tooling to map overlays to their underlying modules, and t
348+
bool isUnderlyingModuleOfCrossImportOverlay(const ModuleDecl *overlay);
349+
350+
/// If \p overlay is a transitively declared cross-import overlay of this
351+
/// module, gets the list of bystander modules that need to be imported
352+
/// alongside this module for the overlay to be loaded.
353+
void getAllBystandersForCrossImportOverlay(
354+
ModuleDecl *overlay, SmallVectorImpl<Identifier> &bystanders);
355+
356+
/// Walks and loads the declared cross-import overlays of this module,
357+
/// transitively, to find all overlays this module underlies.
358+
///
359+
/// This is used by tooling to present these overlays as part of this module.
360+
void findDeclaredCrossImportOverlaysTransitive(
361+
SmallVectorImpl<ModuleDecl *> &overlays);
362+
338363
/// Convenience accessor for clients that know what kind of file they're
339364
/// dealing with.
340365
SourceFile &getMainSourceFile(SourceFileKind expectedKind) const;

Diff for: lib/AST/Module.cpp

+74
Original file line numberDiff line numberDiff line change
@@ -1588,6 +1588,80 @@ void ModuleDecl::getDeclaredCrossImportBystanders(
15881588
otherModules.push_back(std::get<0>(pair));
15891589
}
15901590

1591+
using TransitiveOverlays =
1592+
llvm::SmallDenseMap<ModuleDecl *, std::pair<Identifier, ModuleDecl *>, 1>;
1593+
1594+
static void populateTransitiveCrossImports(ModuleDecl *base,
1595+
TransitiveOverlays &result) {
1596+
if (!result.empty() || !base->mightDeclareCrossImportOverlays())
1597+
return;
1598+
1599+
SmallVector<Identifier, 1> bystanders;
1600+
SmallVector<Identifier, 1> overlays;
1601+
SmallVector<ModuleDecl *, 1> worklist;
1602+
SourceLoc diagLoc; // ignored
1603+
1604+
worklist.push_back(base);
1605+
while (!worklist.empty()) {
1606+
ModuleDecl *current = worklist.back();
1607+
worklist.pop_back();
1608+
if (!current->mightDeclareCrossImportOverlays())
1609+
continue;
1610+
bystanders.clear();
1611+
current->getDeclaredCrossImportBystanders(bystanders);
1612+
for (Identifier bystander: bystanders) {
1613+
overlays.clear();
1614+
current->findDeclaredCrossImportOverlays(bystander, overlays, diagLoc);
1615+
for (Identifier overlay: overlays) {
1616+
if (!overlay.str().startswith("_"))
1617+
continue;
1618+
ModuleDecl *overlayMod =
1619+
base->getASTContext().getModuleByName(overlay.str());
1620+
if (!overlayMod)
1621+
continue;
1622+
if (result.insert({overlayMod, {bystander, current}}).second)
1623+
worklist.push_back(overlayMod);
1624+
}
1625+
}
1626+
}
1627+
}
1628+
1629+
bool ModuleDecl::isUnderlyingModuleOfCrossImportOverlay(
1630+
const ModuleDecl *overlay) {
1631+
if (!overlay->getNameStr().startswith("_"))
1632+
return false;
1633+
1634+
populateTransitiveCrossImports(this, declaredCrossImportsTransitive);
1635+
return declaredCrossImportsTransitive.find(overlay) !=
1636+
declaredCrossImportsTransitive.end();
1637+
}
1638+
1639+
void ModuleDecl::getAllBystandersForCrossImportOverlay(
1640+
ModuleDecl *overlay, SmallVectorImpl<Identifier> &bystanders) {
1641+
if (!overlay->getNameStr().startswith("_"))
1642+
return;
1643+
1644+
populateTransitiveCrossImports(this, declaredCrossImportsTransitive);
1645+
1646+
auto end = declaredCrossImportsTransitive.end();
1647+
for (auto i = declaredCrossImportsTransitive.find(overlay);
1648+
i != end;
1649+
i = declaredCrossImportsTransitive.find(i->second.second)) {
1650+
bystanders.push_back(i->second.first);
1651+
}
1652+
}
1653+
1654+
void ModuleDecl::findDeclaredCrossImportOverlaysTransitive(
1655+
SmallVectorImpl<ModuleDecl *> &overlayModules) {
1656+
populateTransitiveCrossImports(this, declaredCrossImportsTransitive);
1657+
std::transform(declaredCrossImportsTransitive.begin(),
1658+
declaredCrossImportsTransitive.end(),
1659+
std::back_inserter(overlayModules),
1660+
[](TransitiveOverlays::iterator::value_type &i) {
1661+
return i.first;
1662+
});
1663+
}
1664+
15911665
namespace {
15921666
struct OverlayFileContents {
15931667
struct Module {

0 commit comments

Comments
 (0)