Skip to content

Commit c0402fa

Browse files
committed
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.
1 parent 5437959 commit c0402fa

File tree

12 files changed

+216
-0
lines changed

12 files changed

+216
-0
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
struct OtherStruct {
2+
let x: Int
3+
let y: Int
4+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %sourcekitd-test -req=index-to-store %s -index-store-path %t/idx -index-unit-output-path %t/indexstore_multifile.o -- -c -module-name indexstoremodule -o args_output_path.o %s %S/Inputs/indexstore_multifile_other.swift
3+
// RUN: c-index-test core -print-unit %t/idx | %FileCheck --dump-input=always --dump-input-filter=all %s
4+
5+
struct Foo {
6+
let bar: Int
7+
let counter: Int
8+
let other: OtherStruct
9+
10+
init(bar: Int, counter: Int = 0, other: OtherStruct) {
11+
self.bar = bar
12+
self.counter = counter
13+
self.other = other
14+
}
15+
}
16+
17+
// CHECK: indexstore_multifile.o-{{.*}}
18+
// CHECK: module-name: indexstoremodule
19+
// CHECK: main-path: SOURCE_DIR{{/|\\}}test{{/|\\}}SourceKit{{/|\\}}Indexing{{/|\\}}indexstore_multifile.swift
20+
// CHECK: out-file: BUILD_DIR{{.*}}indexstore_multifile.o
21+
// CHECK: is-debug: 1
22+
// CHECK: Unit | system | Swift | {{.*}}{{/|\\}}Swift.swiftmodule
23+
// CHECK: Record | user | SOURCE_DIR{{/|\\}}test{{/|\\}}SourceKit{{/|\\}}Indexing{{/|\\}}indexstore_multifile.swift | indexstore_multifile.swift-{{.*}}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %sourcekitd-test -req=index-to-store %s -index-store-path %t/idx -index-unit-output-path %t/indexstore_with_remappings.o -- -c -module-name indexstoremodule -file-prefix-map %S=REMAPPED_SRC_ROOT -file-prefix-map %t=REMAPPED_OUT_DIR %s
3+
// RUN: c-index-test core -print-unit %t/idx | %FileCheck %s
4+
5+
class Foo {
6+
let member: Int
7+
init(member: Int) {
8+
self.member = member
9+
}
10+
}
11+
12+
// CHECK: indexstore_with_remappings.o-{{.*}}
13+
// CHECK: module-name: indexstoremodule
14+
// CHECK: main-path: REMAPPED_SRC_ROOT{{/|\\}}indexstore_with_remappings.swift
15+
// CHECK: out-file: REMAPPED_OUT_DIR{{/|\\}}indexstore_with_remappings.o
16+
// CHECK: is-debug: 1
17+
// CHECK: Unit | system | Swift | {{.*}}{{/|\\}}Swift.swiftmodule

tools/SourceKit/include/SourceKit/Core/LangSupport.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -873,10 +873,18 @@ struct RenameLocations {
873873
std::vector<RenameLocation> LineColumnLocs;
874874
};
875875

876+
struct IndexStoreOptions {
877+
std::string IndexStorePath;
878+
std::string IndexUnitOutputPath;
879+
};
880+
881+
struct IndexStoreInfo{};
882+
876883
typedef std::function<void(RequestResult<ArrayRef<CategorizedEdits>> Result)>
877884
CategorizedEditsReceiver;
878885
typedef std::function<void(RequestResult<ArrayRef<CategorizedRenameRanges>> Result)>
879886
CategorizedRenameRangesReceiver;
887+
typedef std::function<void(RequestResult<IndexStoreInfo> Result)> IndexToStoreReceiver;
880888

881889
class DocInfoConsumer {
882890
virtual void anchor();
@@ -987,6 +995,12 @@ class LangSupport {
987995
IndexingConsumer &Consumer,
988996
ArrayRef<const char *> Args) = 0;
989997

998+
virtual void indexToStore(StringRef InputFile,
999+
ArrayRef<const char *> Args,
1000+
IndexStoreOptions Opts,
1001+
SourceKitCancellationToken CancellationToken,
1002+
IndexToStoreReceiver Receiver) = 0;
1003+
9901004
virtual void codeComplete(llvm::MemoryBuffer *InputBuf, unsigned Offset,
9911005
OptionsDictionary *options,
9921006
CodeCompletionConsumer &Consumer,

tools/SourceKit/lib/SwiftLang/SwiftIndexing.cpp

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "swift/Frontend/Frontend.h"
2020
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
2121
#include "swift/Index/Index.h"
22+
#include "swift/Index/IndexRecord.h"
2223
#include "swift/Serialization/SerializedModuleLoader.h"
2324
// This is included only for createLazyResolver(). Move to different header ?
2425
#include "swift/Sema/IDETypeChecking.h"
@@ -367,3 +368,79 @@ void SwiftLangSupport::indexSource(StringRef InputFile,
367368
SKIndexDataConsumer IdxDataConsumer(IdxConsumer);
368369
index::indexSourceFile(CI.getPrimarySourceFile(), IdxDataConsumer);
369370
}
371+
372+
static void emitIndexDataForSourceFile(SourceFile &PrimarySourceFile,
373+
StringRef IndexStorePath,
374+
StringRef IndexUnitOutputPath,
375+
const CompilerInstance &Instance) {
376+
const auto &Invocation = Instance.getInvocation();
377+
const auto &Opts = Invocation.getFrontendOptions();
378+
379+
bool isDebugCompilation;
380+
switch (Invocation.getSILOptions().OptMode) {
381+
case OptimizationMode::NotSet:
382+
case OptimizationMode::NoOptimization:
383+
isDebugCompilation = true;
384+
break;
385+
case OptimizationMode::ForSpeed:
386+
case OptimizationMode::ForSize:
387+
isDebugCompilation = false;
388+
break;
389+
}
390+
391+
(void) index::indexAndRecord(&PrimarySourceFile, IndexUnitOutputPath,
392+
IndexStorePath,
393+
!Opts.IndexIgnoreClangModules,
394+
Opts.IndexSystemModules,
395+
Opts.IndexIgnoreStdlib,
396+
Opts.IndexIncludeLocals,
397+
isDebugCompilation,
398+
Invocation.getTargetTriple(),
399+
*Instance.getDependencyTracker(),
400+
Invocation.getIRGenOptions().FilePrefixMap);
401+
}
402+
403+
void SwiftLangSupport::indexToStore(
404+
StringRef PrimaryFilePath, ArrayRef<const char *> Args,
405+
IndexStoreOptions Opts,
406+
SourceKitCancellationToken CancellationToken,
407+
IndexToStoreReceiver Receiver) {
408+
std::string Error;
409+
SwiftInvocationRef Invok =
410+
ASTMgr->getTypecheckInvocation(Args, PrimaryFilePath, Error);
411+
if (!Invok) {
412+
LOG_WARN_FUNC("failed to create an ASTInvocation: " << Error);
413+
Receiver(RequestResult<IndexStoreInfo>::fromError(Error));
414+
return;
415+
}
416+
417+
struct IndexStoreASTConsumer : public SwiftASTConsumer {
418+
IndexToStoreReceiver Receiver;
419+
IndexStoreOptions Opts;
420+
421+
IndexStoreASTConsumer(IndexToStoreReceiver Receiver, IndexStoreOptions Opts)
422+
: Receiver(std::move(Receiver)), Opts(std::move(Opts)) {}
423+
424+
void handlePrimaryAST(ASTUnitRef AstUnit) override {
425+
auto &SF = AstUnit->getPrimarySourceFile();
426+
auto &CI = AstUnit->getCompilerInstance();
427+
emitIndexDataForSourceFile(
428+
SF, Opts.IndexStorePath, Opts.IndexUnitOutputPath, CI);
429+
Receiver(RequestResult<IndexStoreInfo>::fromResult(IndexStoreInfo{}));
430+
}
431+
432+
void cancelled() override {
433+
Receiver(RequestResult<IndexStoreInfo>::cancelled());
434+
}
435+
436+
void failed(StringRef Error) override {
437+
Receiver(RequestResult<IndexStoreInfo>::fromError(Error));
438+
}
439+
};
440+
441+
auto ASTConsumer = std::make_shared<IndexStoreASTConsumer>(std::move(Receiver), std::move(Opts));
442+
getASTManager()->processASTAsync(Invok, ASTConsumer,
443+
/*OncePerASTToken=*/nullptr,
444+
CancellationToken,
445+
llvm::vfs::getRealFileSystem());
446+
}

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,12 @@ class SwiftLangSupport : public LangSupport {
563563
void indexSource(StringRef Filename, IndexingConsumer &Consumer,
564564
ArrayRef<const char *> Args) override;
565565

566+
void indexToStore(StringRef InputFile,
567+
ArrayRef<const char *> Args,
568+
IndexStoreOptions Opts,
569+
SourceKitCancellationToken CancellationToken,
570+
IndexToStoreReceiver Receiver) override;
571+
566572
void codeComplete(llvm::MemoryBuffer *InputBuf, unsigned Offset,
567573
OptionsDictionary *options,
568574
SourceKit::CodeCompletionConsumer &Consumer,

tools/SourceKit/tools/sourcekitd-test/Options.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,12 @@ def vfs_files : CommaJoined<["-"], "vfs-files=">,
166166
def vfs_name : Separate<["-"], "vfs-name">,
167167
HelpText<"Specify a virtual filesystem name">;
168168

169+
def index_store_path : Separate<["-"], "index-store-path">,
170+
HelpText<"Index Store path to use for indexing">;
171+
172+
def index_unit_output_path : Separate<["-"], "index-unit-output-path">,
173+
HelpText<"Index Store unit output path to use for indexing">;
174+
169175
def suppress_config_request : Flag<["-"], "suppress-config-request">,
170176
HelpText<"Suppress the default global configuration request, that is otherwise sent before any other request (except for the global-config request itself)">;
171177

tools/SourceKit/tools/sourcekitd-test/TestOptions.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
154154
.Case("compile", SourceKitRequest::Compile)
155155
.Case("compile.close", SourceKitRequest::CompileClose)
156156
.Case("syntactic-expandmacro", SourceKitRequest::SyntacticMacroExpansion)
157+
.Case("index-to-store", SourceKitRequest::IndexToStore)
157158
#define SEMANTIC_REFACTORING(KIND, NAME, ID) .Case("refactoring." #ID, SourceKitRequest::KIND)
158159
#include "swift/Refactoring/RefactoringKinds.def"
159160
.Default(SourceKitRequest::None);
@@ -205,6 +206,7 @@ bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
205206
<< "- global-config\n"
206207
<< "- dependency-updated\n"
207208
<< "- syntactic-expandmacro\n"
209+
<< "- index-to-store\n"
208210
#define SEMANTIC_REFACTORING(KIND, NAME, ID) << "- refactoring." #ID "\n"
209211
#include "swift/Refactoring/RefactoringKinds.def"
210212
"\n";
@@ -428,6 +430,14 @@ bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
428430
VFSName = InputArg->getValue();
429431
break;
430432

433+
case OPT_index_store_path:
434+
IndexStorePath = InputArg->getValue();
435+
break;
436+
437+
case OPT_index_unit_output_path:
438+
IndexUnitOutputPath = InputArg->getValue();
439+
break;
440+
431441
case OPT_module_cache_path:
432442
ModuleCachePath = InputArg->getValue();
433443
break;

tools/SourceKit/tools/sourcekitd-test/TestOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ enum class SourceKitRequest {
7171
Compile,
7272
CompileClose,
7373
SyntacticMacroExpansion,
74+
IndexToStore,
7475
#define SEMANTIC_REFACTORING(KIND, NAME, ID) KIND,
7576
#include "swift/Refactoring/RefactoringKinds.def"
7677
};
@@ -148,6 +149,8 @@ struct TestOptions {
148149
llvm::Optional<std::string> VFSName;
149150
llvm::Optional<bool> CancelOnSubsequentRequest;
150151
bool ShellExecution = false;
152+
std::string IndexStorePath;
153+
std::string IndexUnitOutputPath;
151154
bool parseArgs(llvm::ArrayRef<const char *> Args);
152155
void printHelp(bool ShowHidden) const;
153156
};

tools/SourceKit/tools/sourcekitd-test/sourcekitd-test.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,6 +1153,13 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) {
11531153
RequestSyntacticMacroExpansion);
11541154
setSyntacticMacroExpansions(Req, Opts, SourceBuf.get());
11551155
break;
1156+
1157+
case SourceKitRequest::IndexToStore:
1158+
sourcekitd_request_dictionary_set_string(Req, KeyName, SemaName.c_str());
1159+
sourcekitd_request_dictionary_set_string(Req, KeyIndexStorePath, Opts.IndexStorePath.c_str());
1160+
sourcekitd_request_dictionary_set_string(Req, KeyIndexUnitOutputPath, Opts.IndexUnitOutputPath.c_str());
1161+
sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestIndexToStore);
1162+
break;
11561163
}
11571164

11581165
if (!Opts.SourceFile.empty()) {
@@ -1585,6 +1592,9 @@ static bool handleResponse(sourcekitd_response_t Resp, const TestOptions &Opts,
15851592
case SourceKitRequest::Statistics:
15861593
printStatistics(Info, llvm::outs());
15871594
break;
1595+
case SourceKitRequest::IndexToStore:
1596+
printRawResponse(Resp);
1597+
break;
15881598
}
15891599
}
15901600

0 commit comments

Comments
 (0)