Skip to content

Commit 8c20bcd

Browse files
authored
Merge pull request swiftlang#32147 from hamishknight/modulo-module
2 parents e2951c5 + d26f414 commit 8c20bcd

File tree

11 files changed

+75
-43
lines changed

11 files changed

+75
-43
lines changed

include/swift/AST/TypeCheckRequests.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2494,6 +2494,25 @@ class PrimarySourceFilesRequest
24942494
bool isCached() const { return true; }
24952495
};
24962496

2497+
/// Retrieve the file being used for code completion in the main module.
2498+
// FIXME: This isn't really a type-checking request, if we ever split off a
2499+
// zone for more basic AST requests, this should be moved there.
2500+
class CodeCompletionFileRequest
2501+
: public SimpleRequest<CodeCompletionFileRequest,
2502+
SourceFile *(ModuleDecl *), RequestFlags::Cached> {
2503+
public:
2504+
using SimpleRequest::SimpleRequest;
2505+
2506+
private:
2507+
friend SimpleRequest;
2508+
2509+
SourceFile *evaluate(Evaluator &evaluator, ModuleDecl *mod) const;
2510+
2511+
public:
2512+
// Cached.
2513+
bool isCached() const { return true; }
2514+
};
2515+
24972516
// Allow AnyValue to compare two Type values, even though Type doesn't
24982517
// support ==.
24992518
template<>

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ SWIFT_REQUEST(TypeChecker, CheckRedeclarationRequest,
3636
Uncached, NoLocationInfo)
3737
SWIFT_REQUEST(TypeChecker, ClassAncestryFlagsRequest,
3838
AncestryFlags(ClassDecl *), Cached, NoLocationInfo)
39+
SWIFT_REQUEST(TypeChecker, CodeCompletionFileRequest,
40+
SourceFile *(ModuleDecl *), Cached, NoLocationInfo)
3941
SWIFT_REQUEST(TypeChecker, CompareDeclSpecializationRequest,
4042
bool (DeclContext *, ValueDecl *, ValueDecl *, bool), Cached,
4143
NoLocationInfo)

include/swift/Frontend/Frontend.h

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -451,9 +451,6 @@ class CompilerInstance {
451451
/// considered primaries.
452452
llvm::SetVector<unsigned> PrimaryBufferIDs;
453453

454-
/// The file that has been registered for code completion.
455-
NullablePtr<SourceFile> CodeCompletionFile;
456-
457454
/// Return whether there is an entry in PrimaryInputs for buffer \p BufID.
458455
bool isPrimaryInput(unsigned BufID) const {
459456
return PrimaryBufferIDs.count(BufID) != 0;
@@ -509,8 +506,13 @@ class CompilerInstance {
509506

510507
UnifiedStatsReporter *getStatsReporter() const { return Stats.get(); }
511508

509+
/// Retrieve the main module containing the files being compiled.
512510
ModuleDecl *getMainModule() const;
513511

512+
/// Replace the current main module with a new one. This is used for top-level
513+
/// cached code completion.
514+
void setMainModule(ModuleDecl *newMod);
515+
514516
MemoryBufferSerializedModuleLoader *
515517
getMemoryBufferSerializedModuleLoader() const {
516518
return MemoryBufferLoader;
@@ -557,12 +559,7 @@ class CompilerInstance {
557559

558560
/// If a code completion buffer has been set, returns the corresponding source
559561
/// file.
560-
NullablePtr<SourceFile> getCodeCompletionFile() { return CodeCompletionFile; }
561-
562-
/// Set a new file that we're performing code completion on.
563-
void setCodeCompletionFile(SourceFile *file) {
564-
CodeCompletionFile = file;
565-
}
562+
SourceFile *getCodeCompletionFile() const;
566563

567564
private:
568565
/// Set up the file system by loading and validating all VFS overlay YAML

include/swift/IDE/CompletionInstance.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ class CompletionInstance {
4343
std::mutex mtx;
4444

4545
std::unique_ptr<CompilerInstance> CachedCI;
46-
ModuleDecl *CurrentModule = nullptr;
4746
llvm::hash_code CachedArgHash;
4847
llvm::sys::TimePoint<> DependencyCheckedTimestamp;
4948
llvm::StringMap<llvm::hash_code> InMemoryDependencyHash;

lib/AST/Module.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,20 @@ ArrayRef<SourceFile *> ModuleDecl::getPrimarySourceFiles() const {
532532
return evaluateOrDefault(eval, PrimarySourceFilesRequest{mutableThis}, {});
533533
}
534534

535+
SourceFile *CodeCompletionFileRequest::evaluate(Evaluator &evaluator,
536+
ModuleDecl *mod) const {
537+
const auto &SM = mod->getASTContext().SourceMgr;
538+
assert(mod->isMainModule() && "Can only do completion in the main module");
539+
assert(SM.hasCodeCompletionBuffer() && "Not performing code completion?");
540+
541+
for (auto *file : mod->getFiles()) {
542+
auto *SF = dyn_cast<SourceFile>(file);
543+
if (SF && SF->getBufferID() == SM.getCodeCompletionBufferID())
544+
return SF;
545+
}
546+
llvm_unreachable("Couldn't find the completion file?");
547+
}
548+
535549
#define FORWARD(name, args) \
536550
for (const FileUnit *file : getFiles()) \
537551
file->name args;

lib/Frontend/Frontend.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,12 @@ Optional<unsigned> CompilerInstance::setUpCodeCompletionBuffer() {
489489
return codeCompletionBufferID;
490490
}
491491

492+
SourceFile *CompilerInstance::getCodeCompletionFile() const {
493+
auto *mod = getMainModule();
494+
auto &eval = mod->getASTContext().evaluator;
495+
return evaluateOrDefault(eval, CodeCompletionFileRequest{mod}, nullptr);
496+
}
497+
492498
static bool shouldTreatSingleInputAsMain(InputFileKind inputKind) {
493499
switch (inputKind) {
494500
case InputFileKind::Swift:
@@ -707,6 +713,12 @@ ModuleDecl *CompilerInstance::getMainModule() const {
707713
return MainModule;
708714
}
709715

716+
void CompilerInstance::setMainModule(ModuleDecl *newMod) {
717+
assert(newMod->isMainModule());
718+
MainModule = newMod;
719+
Context->LoadedModules[newMod->getName()] = newMod;
720+
}
721+
710722
void CompilerInstance::performParseOnly(bool EvaluateConditionals,
711723
bool CanDelayBodies) {
712724
const InputFileKind Kind = Invocation.getInputKind();
@@ -899,12 +911,6 @@ SourceFile *CompilerInstance::createSourceFileForMainModule(
899911
if (isPrimary) {
900912
inputFile->enableInterfaceHash();
901913
}
902-
903-
if (bufferID == SourceMgr.getCodeCompletionBufferID()) {
904-
assert(!CodeCompletionFile && "Multiple code completion files?");
905-
CodeCompletionFile = inputFile;
906-
}
907-
908914
return inputFile;
909915
}
910916

lib/IDE/CompletionInstance.cpp

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,10 @@ static DeclContext *getEquivalentDeclContextFromSourceFile(DeclContext *DC,
169169
/// returns \c true. Returns \c true if any callback call returns \c true, \c
170170
/// false otherwise.
171171
static bool
172-
forEachDependencyUntilTrue(CompilerInstance &CI, ModuleDecl *CurrentModule,
173-
unsigned excludeBufferID,
172+
forEachDependencyUntilTrue(CompilerInstance &CI, unsigned excludeBufferID,
174173
llvm::function_ref<bool(StringRef)> callback) {
175174
// Check files in the current module.
176-
for (FileUnit *file : CurrentModule->getFiles()) {
175+
for (FileUnit *file : CI.getMainModule()->getFiles()) {
177176
StringRef filename;
178177
if (auto SF = dyn_cast<SourceFile>(file)) {
179178
if (SF->getBufferID() == excludeBufferID)
@@ -203,12 +202,11 @@ forEachDependencyUntilTrue(CompilerInstance &CI, ModuleDecl *CurrentModule,
203202

204203
/// Collect hash codes of the dependencies into \c Map.
205204
static void cacheDependencyHashIfNeeded(CompilerInstance &CI,
206-
ModuleDecl *CurrentModule,
207205
unsigned excludeBufferID,
208206
llvm::StringMap<llvm::hash_code> &Map) {
209207
auto &FS = CI.getFileSystem();
210208
forEachDependencyUntilTrue(
211-
CI, CurrentModule, excludeBufferID, [&](StringRef filename) {
209+
CI, excludeBufferID, [&](StringRef filename) {
212210
if (Map.count(filename))
213211
return false;
214212

@@ -229,12 +227,12 @@ static void cacheDependencyHashIfNeeded(CompilerInstance &CI,
229227

230228
/// Check if any dependent files are modified since \p timestamp.
231229
static bool areAnyDependentFilesInvalidated(
232-
CompilerInstance &CI, ModuleDecl *CurrentModule, llvm::vfs::FileSystem &FS,
230+
CompilerInstance &CI, llvm::vfs::FileSystem &FS,
233231
unsigned excludeBufferID, llvm::sys::TimePoint<> timestamp,
234232
llvm::StringMap<llvm::hash_code> &Map) {
235233

236234
return forEachDependencyUntilTrue(
237-
CI, CurrentModule, excludeBufferID, [&](StringRef filePath) {
235+
CI, excludeBufferID, [&](StringRef filePath) {
238236
auto stat = FS.status(filePath);
239237
if (!stat)
240238
// Missing.
@@ -291,7 +289,7 @@ bool CompletionInstance::performCachedOperationIfPossible(
291289
return false;
292290

293291
auto &CI = *CachedCI;
294-
auto *oldSF = CI.getCodeCompletionFile().get();
292+
auto *oldSF = CI.getCodeCompletionFile();
295293

296294
auto *oldState = oldSF->getDelayedParserState();
297295
assert(oldState->hasCodeCompletionDelayedDeclState());
@@ -304,7 +302,7 @@ bool CompletionInstance::performCachedOperationIfPossible(
304302

305303
if (shouldCheckDependencies()) {
306304
if (areAnyDependentFilesInvalidated(
307-
CI, CurrentModule, *FileSystem, SM.getCodeCompletionBufferID(),
305+
CI, *FileSystem, SM.getCodeCompletionBufferID(),
308306
DependencyCheckedTimestamp, InMemoryDependencyHash))
309307
return false;
310308
DependencyCheckedTimestamp = std::chrono::system_clock::now();
@@ -441,22 +439,21 @@ bool CompletionInstance::performCachedOperationIfPossible(
441439

442440
// Create a new module and a source file using the current AST context.
443441
auto &Ctx = oldM->getASTContext();
444-
auto *newM =
445-
ModuleDecl::create(oldM->getName(), Ctx, oldM->getImplicitImportInfo());
442+
auto *newM = ModuleDecl::createMainModule(Ctx, oldM->getName(),
443+
oldM->getImplicitImportInfo());
446444
auto *newSF =
447445
new (Ctx) SourceFile(*newM, SourceFileKind::Main, newBufferID);
448446
newM->addFile(*newSF);
449447
newSF->enableInterfaceHash();
450448

451-
// Tell the compiler instance we've replaced the code completion file.
452-
CI.setCodeCompletionFile(newSF);
449+
// Tell the compiler instance we've replaced the main module.
450+
CI.setMainModule(newM);
453451

454452
// Re-process the whole file (parsing will be lazily triggered). Still
455453
// re-use imported modules.
456454
performImportResolution(*newSF);
457455
bindExtensions(*newM);
458456

459-
CurrentModule = newM;
460457
traceDC = newM;
461458
#ifndef NDEBUG
462459
const auto *reparsedState = newSF->getDelayedParserState();
@@ -483,7 +480,7 @@ bool CompletionInstance::performCachedOperationIfPossible(
483480
}
484481

485482
CachedReuseCount += 1;
486-
cacheDependencyHashIfNeeded(CI, CurrentModule, SM.getCodeCompletionBufferID(),
483+
cacheDependencyHashIfNeeded(CI, SM.getCodeCompletionBufferID(),
487484
InMemoryDependencyHash);
488485

489486
return true;
@@ -536,8 +533,7 @@ bool CompletionInstance::performNewOperation(
536533
CI.performParseAndResolveImportsOnly();
537534

538535
// If we didn't find a code completion token, bail.
539-
auto completionFile = CI.getCodeCompletionFile();
540-
auto *state = completionFile.get()->getDelayedParserState();
536+
auto *state = CI.getCodeCompletionFile()->getDelayedParserState();
541537
if (!state->hasCodeCompletionDelayedDeclState())
542538
return true;
543539

@@ -554,14 +550,13 @@ bool CompletionInstance::performNewOperation(
554550
void CompletionInstance::cacheCompilerInstance(
555551
std::unique_ptr<CompilerInstance> CI, llvm::hash_code ArgsHash) {
556552
CachedCI = std::move(CI);
557-
CurrentModule = CachedCI->getMainModule();
558553
CachedArgHash = ArgsHash;
559554
auto now = std::chrono::system_clock::now();
560555
DependencyCheckedTimestamp = now;
561556
CachedReuseCount = 0;
562557
InMemoryDependencyHash.clear();
563558
cacheDependencyHashIfNeeded(
564-
*CachedCI, CurrentModule,
559+
*CachedCI,
565560
CachedCI->getASTContext().SourceMgr.getCodeCompletionBufferID(),
566561
InMemoryDependencyHash);
567562
}

tools/SourceKit/lib/SwiftLang/SwiftCompletion.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ static bool swiftCodeCompleteImpl(
142142
SwiftConsumer.setContext(&CI.getASTContext(), &CI.getInvocation(),
143143
&CompletionContext);
144144

145-
auto SF = CI.getCodeCompletionFile();
146-
performCodeCompletionSecondPass(*SF.get(), *callbacksFactory);
145+
auto *SF = CI.getCodeCompletionFile();
146+
performCodeCompletionSecondPass(*SF, *callbacksFactory);
147147
SwiftConsumer.clearContext();
148148
});
149149
}

tools/SourceKit/lib/SwiftLang/SwiftConformingMethodList.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ static bool swiftConformingMethodListImpl(
4242
ide::makeConformingMethodListCallbacksFactory(ExpectedTypeNames,
4343
Consumer));
4444

45-
auto SF = CI.getCodeCompletionFile();
46-
performCodeCompletionSecondPass(*SF.get(), *callbacksFactory);
45+
auto *SF = CI.getCodeCompletionFile();
46+
performCodeCompletionSecondPass(*SF, *callbacksFactory);
4747
});
4848
}
4949

tools/SourceKit/lib/SwiftLang/SwiftTypeContextInfo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ static bool swiftTypeContextInfoImpl(
3939
std::unique_ptr<CodeCompletionCallbacksFactory> callbacksFactory(
4040
ide::makeTypeContextInfoCallbacksFactory(Consumer));
4141

42-
auto SF = CI.getCodeCompletionFile();
43-
performCodeCompletionSecondPass(*SF.get(), *callbacksFactory);
42+
auto *SF = CI.getCodeCompletionFile();
43+
performCodeCompletionSecondPass(*SF, *callbacksFactory);
4444
});
4545
}
4646

0 commit comments

Comments
 (0)