Skip to content

Commit 33336df

Browse files
committed
[SouceKit] Make "ASTContext reusing" optional
for 'ConformingMethodList' and 'TypeContextInfo'
1 parent 8307c6a commit 33336df

File tree

9 files changed

+113
-42
lines changed

9 files changed

+113
-42
lines changed

test/SourceKit/ConformingMethods/basic.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,10 @@ func testing(obj: C) {
2828

2929
// RUN: %sourcekitd-test -req=conformingmethods -pos=26:14 -repeat-request=2 %s -req-opts=expectedtypes='$s8MyModule7Target2PD;$s8MyModule7Target1PD' -- -module-name MyModule %s > %t.response
3030
// RUN: %diff -u %s.response %t.response
31+
// RUN: %sourcekitd-test -req=conformingmethods -pos=26:14 -repeat-request=2 %s -req-opts=expectedtypes='$s8MyModule7Target2PD;$s8MyModule7Target1PD',reuseastcontext=0 -- -module-name MyModule %s | %FileCheck %s --check-prefix=DISABLED
32+
33+
// DISABLED-NOT: key.reuseastcontext
34+
// DISABLED: key.members: [
35+
// DISABLED-NOT: key.reuseastcontext
36+
// DISABLED: key.members: [
37+
// DISABLED-NOT: key.reuseastcontext

test/SourceKit/TypeContextInfo/typecontext_basic.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,10 @@ func test(obj: C) {
2727

2828
// RUN: %sourcekitd-test -req=typecontextinfo -repeat-request=2 -pos=25:22 %s -- %s > %t.response
2929
// RUN: %diff -u %s.response %t.response
30+
// RUN: %sourcekitd-test -req=typecontextinfo -repeat-request=2 -pos=25:22 %s -req-opts=reuseastcontext=0 -- %s | %FileCheck %s --check-prefix=DISABLED
31+
32+
// DISABLED-NOT: key.reuseastcontext
33+
// DISABLED: key.results: [
34+
// DISABLED-NOT: key.reuseastcontext
35+
// DISABLED: key.results: [
36+
// DISABLED-NOT: key.reuseastcontext

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,12 +813,14 @@ class LangSupport {
813813

814814
virtual void getExpressionContextInfo(llvm::MemoryBuffer *inputBuf,
815815
unsigned Offset,
816+
OptionsDictionary *options,
816817
ArrayRef<const char *> Args,
817818
TypeContextInfoConsumer &Consumer,
818819
Optional<VFSOptions> vfsOptions) = 0;
819820

820821
virtual void getConformingMethodList(llvm::MemoryBuffer *inputBuf,
821822
unsigned Offset,
823+
OptionsDictionary *options,
822824
ArrayRef<const char *> Args,
823825
ArrayRef<const char *> ExpectedTypes,
824826
ConformingMethodListConsumer &Consumer,

tools/SourceKit/lib/SwiftLang/SwiftConformingMethodList.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ using namespace SourceKit;
2626
using namespace swift;
2727
using namespace ide;
2828

29+
static void translateConformingMethodListOptions(OptionsDictionary &from,
30+
ConformingMethodList::Options &to) {
31+
static UIdent KeyReuseASTContext("key.conformingmethods.reuseastcontext");
32+
33+
from.valueForOption(KeyReuseASTContext, to.reuseASTContextIfPossible);
34+
}
35+
2936
static bool swiftConformingMethodListImpl(
3037
SwiftLangSupport &Lang, llvm::MemoryBuffer *UnresolvedInputFile,
3138
unsigned Offset, ArrayRef<const char *> Args,
@@ -50,7 +57,8 @@ static bool swiftConformingMethodListImpl(
5057

5158
void SwiftLangSupport::getConformingMethodList(
5259
llvm::MemoryBuffer *UnresolvedInputFile, unsigned Offset,
53-
ArrayRef<const char *> Args, ArrayRef<const char *> ExpectedTypeNames,
60+
OptionsDictionary *optionsDict, ArrayRef<const char *> Args,
61+
ArrayRef<const char *> ExpectedTypeNames,
5462
SourceKit::ConformingMethodListConsumer &SKConsumer,
5563
Optional<VFSOptions> vfsOptions) {
5664
std::string error;
@@ -61,6 +69,11 @@ void SwiftLangSupport::getConformingMethodList(
6169
if (!fileSystem)
6270
return SKConsumer.failed(error);
6371

72+
ConformingMethodList::Options options;
73+
if (optionsDict) {
74+
translateConformingMethodListOptions(*optionsDict, options);
75+
}
76+
6477
class Consumer : public ide::ConformingMethodListConsumer {
6578
SourceKit::ConformingMethodListConsumer &SKConsumer;
6679

@@ -181,7 +194,7 @@ void SwiftLangSupport::getConformingMethodList(
181194

182195
if (!swiftConformingMethodListImpl(*this, UnresolvedInputFile, Offset, Args,
183196
ExpectedTypeNames, Consumer, fileSystem,
184-
/*EnableASTCaching=*/true, error)) {
197+
options.reuseASTContextIfPossible, error)) {
185198
SKConsumer.failed(error);
186199
}
187200
}

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,18 @@ class SessionCacheMap {
220220
};
221221
} // end namespace CodeCompletion
222222

223+
namespace TypeContextInfo {
224+
struct Options {
225+
bool reuseASTContextIfPossible = true;
226+
};
227+
} // namespace TypeContextInfo
228+
229+
namespace ConformingMethodList {
230+
struct Options {
231+
bool reuseASTContextIfPossible = true;
232+
};
233+
} // namespace ConformingMethodList
234+
223235
class SwiftInterfaceGenMap {
224236
llvm::StringMap<SwiftInterfaceGenContextRef> IFaceGens;
225237
mutable llvm::sys::Mutex Mtx;
@@ -606,11 +618,13 @@ class SwiftLangSupport : public LangSupport {
606618
std::function<void(const RequestResult<ArrayRef<StringRef>> &)> Receiver) override;
607619

608620
void getExpressionContextInfo(llvm::MemoryBuffer *inputBuf, unsigned Offset,
621+
OptionsDictionary *options,
609622
ArrayRef<const char *> Args,
610623
TypeContextInfoConsumer &Consumer,
611624
Optional<VFSOptions> vfsOptions) override;
612625

613626
void getConformingMethodList(llvm::MemoryBuffer *inputBuf, unsigned Offset,
627+
OptionsDictionary *options,
614628
ArrayRef<const char *> Args,
615629
ArrayRef<const char *> ExpectedTypes,
616630
ConformingMethodListConsumer &Consumer,

tools/SourceKit/lib/SwiftLang/SwiftTypeContextInfo.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,13 @@ using namespace SourceKit;
2525
using namespace swift;
2626
using namespace ide;
2727

28+
static void translateTypeContextInfoOptions(OptionsDictionary &from,
29+
TypeContextInfo::Options &to) {
30+
static UIdent KeyReuseASTContext("key.typecontextinfo.reuseastcontext");
31+
32+
from.valueForOption(KeyReuseASTContext, to.reuseASTContextIfPossible);
33+
}
34+
2835
static bool swiftTypeContextInfoImpl(
2936
SwiftLangSupport &Lang, llvm::MemoryBuffer *UnresolvedInputFile,
3037
unsigned Offset, ide::TypeContextInfoConsumer &Consumer,
@@ -47,11 +54,16 @@ static bool swiftTypeContextInfoImpl(
4754

4855
void SwiftLangSupport::getExpressionContextInfo(
4956
llvm::MemoryBuffer *UnresolvedInputFile, unsigned Offset,
50-
ArrayRef<const char *> Args,
57+
OptionsDictionary *optionsDict, ArrayRef<const char *> Args,
5158
SourceKit::TypeContextInfoConsumer &SKConsumer,
5259
Optional<VFSOptions> vfsOptions) {
5360
std::string error;
5461

62+
TypeContextInfo::Options options;
63+
if (optionsDict) {
64+
translateTypeContextInfoOptions(*optionsDict, options);
65+
}
66+
5567
// FIXME: the use of None as primary file is to match the fact we do not read
5668
// the document contents using the editor documents infrastructure.
5769
auto fileSystem = getFileSystem(vfsOptions, /*primaryFile=*/None, error);
@@ -156,8 +168,8 @@ void SwiftLangSupport::getExpressionContextInfo(
156168
} Consumer(SKConsumer);
157169

158170
if (!swiftTypeContextInfoImpl(*this, UnresolvedInputFile, Offset, Consumer,
159-
Args, fileSystem, /*EnableASTCaching=*/true,
160-
error)) {
171+
Args, fileSystem,
172+
options.reuseASTContextIfPossible, error)) {
161173
SKConsumer.failed(error);
162174
}
163175
}

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

Lines changed: 29 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -298,28 +298,42 @@ static int printDiags();
298298

299299
static void getSemanticInfo(sourcekitd_variant_t Info, StringRef Filename);
300300

301-
static void addCodeCompleteOptions(sourcekitd_object_t Req, TestOptions &Opts) {
301+
static void addRequestOptions(sourcekitd_object_t Req, TestOptions &Opts,
302+
sourcekitd_uid_t Key, StringRef(prefix)) {
302303
if (!Opts.RequestOptions.empty()) {
303304
sourcekitd_object_t CCOpts =
304305
sourcekitd_request_dictionary_create(nullptr, nullptr, 0);
305306
for (auto &Opt : Opts.RequestOptions) {
306307
auto KeyValue = StringRef(Opt).split('=');
307-
std::string KeyStr("key.codecomplete.");
308+
std::string KeyStr(prefix.str());
308309
KeyStr.append(KeyValue.first.str());
309310
sourcekitd_uid_t Key = sourcekitd_uid_get_from_cstr(KeyStr.c_str());
310311

311312
// FIXME: more robust way to determine the option type.
312313
if (KeyValue.first == "filtertext") {
313314
sourcekitd_request_dictionary_set_stringbuf(
314315
CCOpts, Key, KeyValue.second.data(), KeyValue.second.size());
316+
} else if (KeyValue.first == "expectedtypes") {
317+
SmallVector<StringRef, 4> expectedTypeNames;
318+
KeyValue.second.split(expectedTypeNames, ';');
319+
320+
auto typenames = sourcekitd_request_array_create(nullptr, 0);
321+
for (auto &name : expectedTypeNames) {
322+
std::string n = name.str();
323+
sourcekitd_request_array_set_string(typenames,
324+
SOURCEKITD_ARRAY_APPEND,
325+
n.c_str());
326+
}
327+
// NOTE: 'key.expectedtypes' directly to the request.
328+
sourcekitd_request_dictionary_set_value(Req, KeyExpectedTypes,
329+
typenames);
315330
} else {
316331
int64_t Value = 0;
317332
KeyValue.second.getAsInteger(0, Value);
318333
sourcekitd_request_dictionary_set_int64(CCOpts, Key, Value);
319334
}
320335
}
321-
sourcekitd_request_dictionary_set_value(Req, KeyCodeCompleteOptions,
322-
CCOpts);
336+
sourcekitd_request_dictionary_set_value(Req, Key, CCOpts);
323337
sourcekitd_request_release(CCOpts);
324338
}
325339
}
@@ -444,28 +458,6 @@ static int handleTestInvocation(ArrayRef<const char *> Args,
444458
return 0;
445459
}
446460

447-
static int setExpectedTypes(const sourcekitd_test::TestOptions &Opts,
448-
sourcekitd_object_t Req) {
449-
for (auto &Opt : Opts.RequestOptions) {
450-
auto KeyValue = StringRef(Opt).split('=');
451-
if (KeyValue.first == "expectedtypes") {
452-
SmallVector<StringRef, 4> expectedTypeNames;
453-
KeyValue.second.split(expectedTypeNames, ';');
454-
455-
auto typenames = sourcekitd_request_array_create(nullptr, 0);
456-
for (auto &name : expectedTypeNames) {
457-
std::string n = name.str();
458-
sourcekitd_request_array_set_string(typenames, SOURCEKITD_ARRAY_APPEND, n.c_str());
459-
}
460-
sourcekitd_request_dictionary_set_value(Req, KeyExpectedTypes, typenames);
461-
} else {
462-
llvm::errs() << "invalid key '" << KeyValue.first << "' in -req-opts\n";
463-
return 1;
464-
}
465-
}
466-
return 0;
467-
}
468-
469461
static bool sendGlobalConfigRequest() {
470462
TestOptions Opts;
471463
sourcekitd_object_t Req = sourcekitd_request_dictionary_create(nullptr,
@@ -601,15 +593,15 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) {
601593
sourcekitd_request_dictionary_set_string(Req, KeyName, SemaName.c_str());
602594
// Default to sort by name.
603595
Opts.RequestOptions.insert(Opts.RequestOptions.begin(), "sort.byname=1");
604-
addCodeCompleteOptions(Req, Opts);
596+
addRequestOptions(Req, Opts, KeyCodeCompleteOptions, "key.codecomplete.");
605597
break;
606598

607599
case SourceKitRequest::CodeCompleteOpen:
608600
sourcekitd_request_dictionary_set_uid(Req, KeyRequest,
609601
RequestCodeCompleteOpen);
610602
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
611603
sourcekitd_request_dictionary_set_string(Req, KeyName, SemaName.c_str());
612-
addCodeCompleteOptions(Req, Opts);
604+
addRequestOptions(Req, Opts, KeyCodeCompleteOptions, "key.codecomplete.");
613605
break;
614606

615607
case SourceKitRequest::CodeCompleteClose:
@@ -624,7 +616,7 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) {
624616
RequestCodeCompleteUpdate);
625617
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
626618
sourcekitd_request_dictionary_set_string(Req, KeyName, SemaName.c_str());
627-
addCodeCompleteOptions(Req, Opts);
619+
addRequestOptions(Req, Opts, KeyCodeCompleteOptions, "key.codecomplete.");
628620
break;
629621

630622
case SourceKitRequest::CodeCompleteCacheOnDisk:
@@ -673,13 +665,16 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) {
673665
sourcekitd_request_dictionary_set_uid(Req, KeyRequest,
674666
RequestTypeContextInfo);
675667
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
668+
addRequestOptions(Req, Opts, KeyTypeContextInfoOptions,
669+
"key.typecontextinfo.");
676670
break;
677671

678672
case SourceKitRequest::ConformingMethodList:
679673
sourcekitd_request_dictionary_set_uid(Req, KeyRequest,
680674
RequestConformingMethodList);
681675
sourcekitd_request_dictionary_set_int64(Req, KeyOffset, ByteOffset);
682-
setExpectedTypes(Opts, Req);
676+
addRequestOptions(Req, Opts, KeyConformingMethodListOptions,
677+
"key.conformingmethods.");
683678
break;
684679

685680
case SourceKitRequest::CursorInfo:
@@ -711,7 +706,10 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) {
711706

712707
case SourceKitRequest::CollectExpresstionType: {
713708
sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestCollectExpressionType);
714-
setExpectedTypes(Opts, Req);
709+
// NOTE: KeyCodeCompletion and the prefix are just dummy. This request
710+
// only accepts 'expectedtypes' which is placed to the Req root dictionary.
711+
addRequestOptions(Req, Opts, KeyCodeCompleteOptions,
712+
"key.expression.type.");
715713
break;
716714
}
717715

tools/SourceKit/tools/sourcekitd/lib/API/Requests.cpp

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -178,11 +178,13 @@ static sourcekitd_response_t codeCompleteClose(StringRef name, int64_t Offset);
178178

179179
static sourcekitd_response_t typeContextInfo(llvm::MemoryBuffer *InputBuf,
180180
int64_t Offset,
181+
Optional<RequestDict> optionsDict,
181182
ArrayRef<const char *> Args,
182183
Optional<VFSOptions> vfsOptions);
183184

184185
static sourcekitd_response_t
185186
conformingMethodList(llvm::MemoryBuffer *InputBuf, int64_t Offset,
187+
Optional<RequestDict> optionsDict,
186188
ArrayRef<const char *> Args,
187189
ArrayRef<const char *> ExpectedTypes,
188190
Optional<VFSOptions> vfsOptions);
@@ -995,7 +997,9 @@ static void handleSemanticRequest(
995997
int64_t Offset;
996998
if (Req.getInt64(KeyOffset, Offset, /*isOptional=*/false))
997999
return Rec(createErrorRequestInvalid("missing 'key.offset'"));
998-
return Rec(typeContextInfo(InputBuf.get(), Offset, Args,
1000+
Optional<RequestDict> options =
1001+
Req.getDictionary(KeyTypeContextInfoOptions);
1002+
return Rec(typeContextInfo(InputBuf.get(), Offset, options, Args,
9991003
std::move(vfsOptions)));
10001004
}
10011005

@@ -1010,9 +1014,11 @@ static void handleSemanticRequest(
10101014
SmallVector<const char *, 8> ExpectedTypeNames;
10111015
if (Req.getStringArray(KeyExpectedTypes, ExpectedTypeNames, true))
10121016
return Rec(createErrorRequestInvalid("invalid 'key.expectedtypes'"));
1017+
Optional<RequestDict> options =
1018+
Req.getDictionary(KeyConformingMethodListOptions);
10131019
return Rec(
1014-
conformingMethodList(InputBuf.get(), Offset, Args, ExpectedTypeNames,
1015-
std::move(vfsOptions)));
1020+
conformingMethodList(InputBuf.get(), Offset, options, Args,
1021+
ExpectedTypeNames, std::move(vfsOptions)));
10161022
}
10171023

10181024
if (!SourceFile.hasValue())
@@ -2266,6 +2272,7 @@ void SKGroupedCodeCompletionConsumer::setAnnotatedTypename(bool flag) {
22662272

22672273
static sourcekitd_response_t typeContextInfo(llvm::MemoryBuffer *InputBuf,
22682274
int64_t Offset,
2275+
Optional<RequestDict> optionsDict,
22692276
ArrayRef<const char *> Args,
22702277
Optional<VFSOptions> vfsOptions) {
22712278
ResponseBuilder RespBuilder;
@@ -2310,8 +2317,12 @@ static sourcekitd_response_t typeContextInfo(llvm::MemoryBuffer *InputBuf,
23102317
}
23112318
} Consumer(RespBuilder);
23122319

2320+
std::unique_ptr<SKOptionsDictionary> options;
2321+
if (optionsDict)
2322+
options = std::make_unique<SKOptionsDictionary>(*optionsDict);
2323+
23132324
LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
2314-
Lang.getExpressionContextInfo(InputBuf, Offset, Args, Consumer,
2325+
Lang.getExpressionContextInfo(InputBuf, Offset, options.get(), Args, Consumer,
23152326
std::move(vfsOptions));
23162327

23172328
if (Consumer.isError())
@@ -2325,6 +2336,7 @@ static sourcekitd_response_t typeContextInfo(llvm::MemoryBuffer *InputBuf,
23252336

23262337
static sourcekitd_response_t
23272338
conformingMethodList(llvm::MemoryBuffer *InputBuf, int64_t Offset,
2339+
Optional<RequestDict> optionsDict,
23282340
ArrayRef<const char *> Args,
23292341
ArrayRef<const char *> ExpectedTypes,
23302342
Optional<VFSOptions> vfsOptions) {
@@ -2368,9 +2380,13 @@ conformingMethodList(llvm::MemoryBuffer *InputBuf, int64_t Offset,
23682380
}
23692381
} Consumer(RespBuilder);
23702382

2383+
std::unique_ptr<SKOptionsDictionary> options;
2384+
if (optionsDict)
2385+
options = std::make_unique<SKOptionsDictionary>(*optionsDict);
2386+
23712387
LangSupport &Lang = getGlobalContext().getSwiftLangSupport();
2372-
Lang.getConformingMethodList(InputBuf, Offset, Args, ExpectedTypes, Consumer,
2373-
std::move(vfsOptions));
2388+
Lang.getConformingMethodList(InputBuf, Offset, options.get(), Args,
2389+
ExpectedTypes, Consumer, std::move(vfsOptions));
23742390

23752391
if (Consumer.isError())
23762392
return createErrorRequestFailed(Consumer.getErrorDescription());

utils/gyb_sourcekit_support/UIDs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ def __init__(self, internal_name, external_name):
9999
KEY('EducationalNotePaths', 'key.educational_note_paths'),
100100
KEY('FormatOptions', 'key.editor.format.options'),
101101
KEY('CodeCompleteOptions', 'key.codecomplete.options'),
102+
KEY('TypeContextInfoOptions', 'key.typecontextinfo.options'),
103+
KEY('ConformingMethodListOptions', 'key.conformingmethods.options'),
102104
KEY('FilterRules', 'key.codecomplete.filterrules'),
103105
KEY('NextRequestStart', 'key.nextrequeststart'),
104106
KEY('Popular', 'key.popular'),

0 commit comments

Comments
 (0)