Add source.request.index_to_store to sourcekitd

This requests performs an index store index of the given file using the
given index store path and index unit output path. All other options are
derived from the index store related compiler flags.

This will allow IDEs like Xcode to index the file directly inside of
sourcekitd and potentially reuse an already built AST.
This commit is contained in:
David Goldman
2023-06-20 15:29:17 -04:00
parent 12ebe0aab8
commit d618233166
10 changed files with 191 additions and 0 deletions

View File

@@ -19,6 +19,7 @@
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/Index/Index.h"
#include "swift/Index/IndexRecord.h"
#include "swift/Serialization/SerializedModuleLoader.h"
// This is included only for createLazyResolver(). Move to different header ?
#include "swift/Sema/IDETypeChecking.h"
@@ -367,3 +368,81 @@ void SwiftLangSupport::indexSource(StringRef InputFile,
SKIndexDataConsumer IdxDataConsumer(IdxConsumer);
index::indexSourceFile(CI.getPrimarySourceFile(), IdxDataConsumer);
}
static void emitIndexDataForSourceFile(SourceFile &PrimarySourceFile,
StringRef IndexStorePath,
StringRef IndexUnitOutputPath,
const CompilerInstance &Instance) {
const auto &Invocation = Instance.getInvocation();
const auto &Opts = Invocation.getFrontendOptions();
bool isDebugCompilation;
switch (Invocation.getSILOptions().OptMode) {
case OptimizationMode::NotSet:
case OptimizationMode::NoOptimization:
isDebugCompilation = true;
break;
case OptimizationMode::ForSpeed:
case OptimizationMode::ForSize:
isDebugCompilation = false;
break;
}
(void) index::indexAndRecord(&PrimarySourceFile, IndexUnitOutputPath,
IndexStorePath,
!Opts.IndexIgnoreClangModules,
Opts.IndexSystemModules,
Opts.IndexIgnoreStdlib,
Opts.IndexIncludeLocals,
isDebugCompilation,
Invocation.getTargetTriple(),
*Instance.getDependencyTracker(),
Invocation.getIRGenOptions().FilePrefixMap);
}
void SwiftLangSupport::indexToStore(
StringRef InputFile, ArrayRef<const char *> Args,
IndexStoreOptions Opts,
SourceKitCancellationToken CancellationToken,
IndexToStoreReceiver Receiver) {
std::string Error;
SwiftInvocationRef Invok =
ASTMgr->getTypecheckInvocation(Args, InputFile, Error);
if (!Invok) {
LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error);
Receiver(RequestResult<IndexStoreInfo>::fromError(Error));
return;
}
struct IndexStoreASTConsumer : public SwiftASTConsumer {
IndexToStoreReceiver Receiver;
IndexStoreOptions Opts;
IndexStoreASTConsumer(IndexToStoreReceiver Receiver, IndexStoreOptions Opts)
: Receiver(std::move(Receiver)), Opts(std::move(Opts)) {}
void handlePrimaryAST(ASTUnitRef AstUnit) override {
auto &SF = AstUnit->getPrimarySourceFile();
auto &CI = AstUnit->getCompilerInstance();
emitIndexDataForSourceFile(
SF, Opts.IndexStorePath, Opts.IndexUnitOutputPath, CI);
Receiver(RequestResult<IndexStoreInfo>::fromResult(IndexStoreInfo{}));
}
void cancelled() override {
Receiver(RequestResult<IndexStoreInfo>::cancelled());
}
void failed(StringRef Error) override {
Receiver(RequestResult<IndexStoreInfo>::fromError(Error));
}
};
auto ASTConsumer = std::make_shared<IndexStoreASTConsumer>(std::move(Receiver), std::move(Opts));
/// FIXME: When request cancellation is implemented and Xcode adopts it,
/// don't use 'OncePerASTToken'.
static const char OncePerASTToken = 0;
getASTManager()->processASTAsync(Invok, ASTConsumer, &OncePerASTToken,
CancellationToken,
llvm::vfs::getRealFileSystem());
}