Skip to content

Commit 222e2c7

Browse files
committed
Lift ImportDepth utility out of SourceKit into IDE (NFC)
1 parent bdacb68 commit 222e2c7

File tree

3 files changed

+93
-84
lines changed

3 files changed

+93
-84
lines changed

include/swift/IDE/CodeCompletion.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "swift/Basic/Debug.h"
1818
#include "swift/Basic/LLVM.h"
1919
#include "llvm/ADT/ArrayRef.h"
20+
#include "llvm/ADT/StringMap.h"
2021
#include "llvm/ADT/StringRef.h"
2122
#include "llvm/Support/Allocator.h"
2223
#include "llvm/Support/TrailingObjects.h"
@@ -29,6 +30,7 @@ namespace swift {
2930
class CodeCompletionCallbacksFactory;
3031
class Decl;
3132
class DeclContext;
33+
class FrontendOptions;
3234
class ModuleDecl;
3335

3436
namespace ide {
@@ -865,6 +867,26 @@ struct CodeCompletionResultSink {
865867
: Allocator(std::make_shared<llvm::BumpPtrAllocator>()) {}
866868
};
867869

870+
/// A utility for calculating the import depth of a given module. Direct imports
871+
/// have depth 1, imports of those modules have depth 2, etc.
872+
///
873+
/// Special modules such as Playground auxiliary sources are considered depth
874+
/// 0.
875+
class ImportDepth {
876+
llvm::StringMap<uint8_t> depths;
877+
878+
public:
879+
ImportDepth() = default;
880+
ImportDepth(ASTContext &context, const FrontendOptions &frontendOptions);
881+
882+
Optional<uint8_t> lookup(StringRef module) {
883+
auto I = depths.find(module);
884+
if (I == depths.end())
885+
return None;
886+
return I->getValue();
887+
}
888+
};
889+
868890
class CodeCompletionContext {
869891
friend class CodeCompletionResultBuilder;
870892

lib/IDE/CodeCompletion.cpp

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/Basic/LLVM.h"
3131
#include "swift/ClangImporter/ClangImporter.h"
3232
#include "swift/ClangImporter/ClangModule.h"
33+
#include "swift/Frontend/FrontendOptions.h"
3334
#include "swift/IDE/CodeCompletionCache.h"
3435
#include "swift/IDE/CodeCompletionResultPrinter.h"
3536
#include "swift/IDE/Utils.h"
@@ -7010,3 +7011,71 @@ void SimpleCachingCodeCompletionConsumer::handleResultsAndModules(
70107011

70117012
handleResults(context.takeResults());
70127013
}
7014+
7015+
//===----------------------------------------------------------------------===//
7016+
// ImportDepth
7017+
//===----------------------------------------------------------------------===//
7018+
7019+
ImportDepth::ImportDepth(ASTContext &context,
7020+
const FrontendOptions &frontendOptions) {
7021+
llvm::DenseSet<ModuleDecl *> seen;
7022+
std::deque<std::pair<ModuleDecl *, uint8_t>> worklist;
7023+
7024+
StringRef mainModule = frontendOptions.ModuleName;
7025+
auto *main = context.getLoadedModule(context.getIdentifier(mainModule));
7026+
assert(main && "missing main module");
7027+
worklist.emplace_back(main, uint8_t(0));
7028+
7029+
// Imports from -import-name such as Playground auxiliary sources are treated
7030+
// specially by applying import depth 0.
7031+
llvm::StringSet<> auxImports;
7032+
for (const auto &pair : frontendOptions.getImplicitImportModuleNames())
7033+
auxImports.insert(pair.first);
7034+
7035+
// Private imports from this module.
7036+
// FIXME: only the private imports from the current source file.
7037+
// FIXME: ImportFilterKind::ShadowedByCrossImportOverlay?
7038+
SmallVector<ImportedModule, 16> mainImports;
7039+
main->getImportedModules(mainImports,
7040+
{ModuleDecl::ImportFilterKind::Default,
7041+
ModuleDecl::ImportFilterKind::ImplementationOnly});
7042+
for (auto &import : mainImports) {
7043+
uint8_t depth = 1;
7044+
if (auxImports.count(import.importedModule->getName().str()))
7045+
depth = 0;
7046+
worklist.emplace_back(import.importedModule, depth);
7047+
}
7048+
7049+
// Fill depths with BFS over module imports.
7050+
while (!worklist.empty()) {
7051+
ModuleDecl *module;
7052+
uint8_t depth;
7053+
std::tie(module, depth) = worklist.front();
7054+
worklist.pop_front();
7055+
7056+
if (!seen.insert(module).second)
7057+
continue;
7058+
7059+
// Insert new module:depth mapping.
7060+
const clang::Module *CM = module->findUnderlyingClangModule();
7061+
if (CM) {
7062+
depths[CM->getFullModuleName()] = depth;
7063+
} else {
7064+
depths[module->getName().str()] = depth;
7065+
}
7066+
7067+
// Add imports to the worklist.
7068+
SmallVector<ImportedModule, 16> imports;
7069+
module->getImportedModules(imports);
7070+
for (auto &import : imports) {
7071+
uint8_t next = std::max(depth, uint8_t(depth + 1)); // unsigned wrap
7072+
7073+
// Implicitly imported sub-modules get the same depth as their parent.
7074+
if (const clang::Module *CMI =
7075+
import.importedModule->findUnderlyingClangModule())
7076+
if (CM && CMI->isSubModuleOf(CM))
7077+
next = depth;
7078+
worklist.emplace_back(import.importedModule, next);
7079+
}
7080+
}
7081+
}

tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp

Lines changed: 2 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -55,20 +55,6 @@ struct Result : public Item {
5555
return item->getKind() == ItemKind::Result;
5656
}
5757
};
58-
class ImportDepth {
59-
llvm::StringMap<uint8_t> depths;
60-
61-
public:
62-
ImportDepth() = default;
63-
ImportDepth(ASTContext &context, const CompilerInvocation &invocation);
64-
65-
Optional<uint8_t> lookup(StringRef module) {
66-
auto I = depths.find(module);
67-
if (I == depths.end())
68-
return None;
69-
return I->getValue();
70-
}
71-
};
7258
} // end anonymous namespace
7359

7460
struct CodeCompletion::Group : public Item {
@@ -93,7 +79,8 @@ std::vector<Completion *> SourceKit::CodeCompletion::extendCompletions(
9379
ImportDepth depth;
9480
if (info.swiftASTContext) {
9581
// Build import depth map.
96-
depth = ImportDepth(*info.swiftASTContext, *info.invocation);
82+
depth = ImportDepth(*info.swiftASTContext,
83+
info.invocation->getFrontendOptions());
9784
}
9885

9986
if (info.completionContext)
@@ -330,75 +317,6 @@ CodeCompletionViewRef CodeCompletionOrganizer::takeResultsView() {
330317
return impl.takeView();
331318
}
332319

333-
//===----------------------------------------------------------------------===//
334-
// ImportDepth
335-
//===----------------------------------------------------------------------===//
336-
337-
ImportDepth::ImportDepth(ASTContext &context,
338-
const CompilerInvocation &invocation) {
339-
llvm::DenseSet<ModuleDecl *> seen;
340-
std::deque<std::pair<ModuleDecl *, uint8_t>> worklist;
341-
342-
StringRef mainModule = invocation.getModuleName();
343-
auto *main = context.getLoadedModule(context.getIdentifier(mainModule));
344-
assert(main && "missing main module");
345-
worklist.emplace_back(main, uint8_t(0));
346-
347-
// Imports from -import-name such as Playground auxiliary sources are treated
348-
// specially by applying import depth 0.
349-
llvm::StringSet<> auxImports;
350-
for (const auto &pair :
351-
invocation.getFrontendOptions().getImplicitImportModuleNames())
352-
auxImports.insert(pair.first);
353-
354-
// Private imports from this module.
355-
// FIXME: only the private imports from the current source file.
356-
// FIXME: ImportFilterKind::ShadowedByCrossImportOverlay?
357-
SmallVector<ImportedModule, 16> mainImports;
358-
main->getImportedModules(mainImports,
359-
{ModuleDecl::ImportFilterKind::Default,
360-
ModuleDecl::ImportFilterKind::ImplementationOnly});
361-
for (auto &import : mainImports) {
362-
uint8_t depth = 1;
363-
if (auxImports.count(import.importedModule->getName().str()))
364-
depth = 0;
365-
worklist.emplace_back(import.importedModule, depth);
366-
}
367-
368-
// Fill depths with BFS over module imports.
369-
while (!worklist.empty()) {
370-
ModuleDecl *module;
371-
uint8_t depth;
372-
std::tie(module, depth) = worklist.front();
373-
worklist.pop_front();
374-
375-
if (!seen.insert(module).second)
376-
continue;
377-
378-
// Insert new module:depth mapping.
379-
const clang::Module *CM = module->findUnderlyingClangModule();
380-
if (CM) {
381-
depths[CM->getFullModuleName()] = depth;
382-
} else {
383-
depths[module->getName().str()] = depth;
384-
}
385-
386-
// Add imports to the worklist.
387-
SmallVector<ImportedModule, 16> imports;
388-
module->getImportedModules(imports);
389-
for (auto &import : imports) {
390-
uint8_t next = std::max(depth, uint8_t(depth + 1)); // unsigned wrap
391-
392-
// Implicitly imported sub-modules get the same depth as their parent.
393-
if (const clang::Module *CMI =
394-
import.importedModule->findUnderlyingClangModule())
395-
if (CM && CMI->isSubModuleOf(CM))
396-
next = depth;
397-
worklist.emplace_back(import.importedModule, next);
398-
}
399-
}
400-
}
401-
402320
//===----------------------------------------------------------------------===//
403321
// CodeCompletionOrganizer::Impl utilities
404322
//===----------------------------------------------------------------------===//

0 commit comments

Comments
 (0)