Skip to content

Commit 27dc2cf

Browse files
committed
[SourceKit] Add a request kind to notify dependencies are updated
1 parent bcd6416 commit 27dc2cf

File tree

11 files changed

+107
-2
lines changed

11 files changed

+107
-2
lines changed

include/swift/IDE/CompletionInstance.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ class CompletionInstance {
4949
llvm::sys::TimePoint<> DependencyCheckedTimestamp;
5050
llvm::StringMap<llvm::hash_code> InMemoryDependencyHash;
5151
unsigned CachedReuseCount = 0;
52+
std::atomic<bool> CachedCIShouldBeInvalidated;
5253

5354
void cacheCompilerInstance(std::unique_ptr<CompilerInstance> CI,
5455
llvm::hash_code ArgsHash);
@@ -80,8 +81,13 @@ class CompletionInstance {
8081
llvm::function_ref<void(CompilerInstance &, bool)> Callback);
8182

8283
public:
83-
CompletionInstance() {}
84+
CompletionInstance() : CachedCIShouldBeInvalidated(false) {}
8485

86+
// Mark the cached compiler instance "should be invalidated". In the next
87+
// completion, new compiler instance will be used. (Thread safe.)
88+
void markCachedCompilerInstanceShouldBeInvalidated();
89+
90+
// Update options with \c NewOpts. (Thread safe.)
8591
void setOptions(Options NewOpts);
8692

8793
/// Calls \p Callback with a \c CompilerInstance which is prepared for the

lib/IDE/CompletionInstance.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ bool CompletionInstance::performCachedOperationIfPossible(
288288
llvm::PrettyStackTraceString trace(
289289
"While performing cached completion if possible");
290290

291+
// Check the invalidation first. Otherwise, in case no 'CacheCI' exists yet,
292+
// the flag will remain 'true' even after 'CachedCI' is populated.
293+
if (CachedCIShouldBeInvalidated.exchange(false))
294+
return false;
291295
if (!CachedCI)
292296
return false;
293297
if (CachedReuseCount >= Opts.MaxASTReuseCount)
@@ -586,6 +590,10 @@ bool CompletionInstance::shouldCheckDependencies() const {
586590
return threshold <= now;
587591
}
588592

593+
void CompletionInstance::markCachedCompilerInstanceShouldBeInvalidated() {
594+
CachedCIShouldBeInvalidated = true;
595+
}
596+
589597
void CompletionInstance::setOptions(CompletionInstance::Options NewOpts) {
590598
std::lock_guard<std::mutex> lock(mtx);
591599
Opts = NewOpts;
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import ClangFW
2+
import SwiftFW
3+
4+
func foo() {
5+
/*HERE*/
6+
}
7+
8+
// REQUIRES: shell
9+
10+
// RUN: %empty-directory(%t/Frameworks)
11+
// RUN: %empty-directory(%t/MyProject)
12+
13+
// RUN: COMPILER_ARGS=( \
14+
// RUN: -target %target-triple \
15+
// RUN: -module-name MyProject \
16+
// RUN: -F %t/Frameworks \
17+
// RUN: -I %t/MyProject \
18+
// RUN: -import-objc-header %t/MyProject/Bridging.h \
19+
// RUN: %t/MyProject/Library.swift \
20+
// RUN: %s \
21+
// RUN: )
22+
// RUN: INPUT_DIR=%S/Inputs/checkdeps
23+
24+
// RUN: cp -R $INPUT_DIR/MyProject %t/
25+
// RUN: cp -R $INPUT_DIR/ClangFW.framework %t/Frameworks/
26+
// RUN: %empty-directory(%t/Frameworks/SwiftFW.framework/Modules/SwiftFW.swiftmodule)
27+
// RUN: %target-swift-frontend -emit-module -module-name SwiftFW -o %t/Frameworks/SwiftFW.framework/Modules/SwiftFW.swiftmodule/%target-swiftmodule-name $INPUT_DIR/SwiftFW_src/Funcs.swift
28+
29+
// RUN: %sourcekitd-test \
30+
// RUN: -shell -- echo "### Initial" == \
31+
// RUN: -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} == \
32+
33+
// RUN: -shell -- echo '### Modify framework' == \
34+
// RUN: -shell -- %target-swift-frontend -emit-module -module-name SwiftFW -o %t/Frameworks/SwiftFW.framework/Modules/SwiftFW.swiftmodule/%target-swiftmodule-name $INPUT_DIR/SwiftFW_src_mod/Funcs.swift == \
35+
// RUN: -req=dependency-updated -- ${COMPILER_ARGS[@]} == \
36+
// RUN: -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} == \
37+
38+
// RUN: -shell -- echo '### Notify without modifying' == \
39+
// RUN: -req=dependency-updated -- ${COMPILER_ARGS[@]} == \
40+
// RUN: -req=complete -pos=5:3 %s -- ${COMPILER_ARGS[@]} \
41+
42+
// RUN: | %FileCheck %s
43+
44+
// CHECK-LABEL: ### Initial
45+
// CHECK: key.results: [
46+
// CHECK-DAG: key.description: "clangFWFunc()"
47+
// CHECK-DAG: key.description: "swiftFWFunc()"
48+
// CHECK-DAG: key.description: "localClangFunc()"
49+
// CHECK-DAG: key.description: "localSwiftFunc()"
50+
// CHECK: ]
51+
// CHECK-NOT: key.reusingastcontext: 1
52+
53+
// CHECK-LABEL: ### Modify framework
54+
// CHECK: key.results: [
55+
// CHECK-DAG: key.description: "clangFWFunc()"
56+
// CHECK-DAG: key.description: "swiftFWFunc_mod()"
57+
// CHECK-DAG: key.description: "localClangFunc()"
58+
// CHECK-DAG: key.description: "localSwiftFunc()"
59+
// CHECK: ]
60+
// CHECK-NOT: key.reusingastcontext: 1
61+
62+
// CHECK-LABEL: ### Notify without modifying
63+
// CHECK: key.results: [
64+
// CHECK-DAG: key.description: "clangFWFunc()"
65+
// CHECK-DAG: key.description: "swiftFWFunc_mod()"
66+
// CHECK-DAG: key.description: "localClangFunc()"
67+
// CHECK-DAG: key.description: "localSwiftFunc()"
68+
// CHECK: ]
69+
// CHECK-NOT: key.reusingastcontext: 1

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,8 @@ class LangSupport {
659659

660660
virtual void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) {};
661661

662+
virtual void dependencyUpdated() {}
663+
662664
virtual void indexSource(StringRef Filename,
663665
IndexingConsumer &Consumer,
664666
ArrayRef<const char *> Args) = 0;

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,10 @@ void SwiftLangSupport::globalConfigurationUpdated(
303303
configureCompletionInstance(CompletionInst, Config);
304304
}
305305

306+
void SwiftLangSupport::dependencyUpdated() {
307+
CompletionInst->markCachedCompilerInstanceShouldBeInvalidated();
308+
}
309+
306310
UIdent SwiftLangSupport::getUIDForDecl(const Decl *D, bool IsRef) {
307311
return UIdentVisitor(IsRef).visit(const_cast<Decl*>(D));
308312
}

tools/SourceKit/lib/SwiftLang/SwiftLangSupport.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,8 @@ class SwiftLangSupport : public LangSupport {
474474

475475
void globalConfigurationUpdated(std::shared_ptr<GlobalConfig> Config) override;
476476

477+
void dependencyUpdated() override;
478+
477479
void indexSource(StringRef Filename, IndexingConsumer &Consumer,
478480
ArrayRef<const char *> Args) override;
479481

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ bool TestOptions::parseArgs(llvm::ArrayRef<const char *> Args) {
155155
.Case("track-compiles", SourceKitRequest::EnableCompileNotifications)
156156
.Case("collect-type", SourceKitRequest::CollectExpresstionType)
157157
.Case("global-config", SourceKitRequest::GlobalConfiguration)
158+
.Case("dependency-updated", SourceKitRequest::DependencyUpdated)
158159
.Default(SourceKitRequest::None);
159160

160161
if (Request == SourceKitRequest::None) {

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ enum class SourceKitRequest {
6565
EnableCompileNotifications,
6666
CollectExpresstionType,
6767
GlobalConfiguration,
68+
DependencyUpdated,
6869
#define SEMANTIC_REFACTORING(KIND, NAME, ID) KIND,
6970
#include "swift/IDE/RefactoringKinds.def"
7071
};

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,11 @@ static int handleTestInvocation(TestOptions Opts, TestOptions &InitOpts) {
10251025
case SourceKitRequest::Statistics:
10261026
sourcekitd_request_dictionary_set_uid(Req, KeyRequest, RequestStatistics);
10271027
break;
1028+
1029+
case SourceKitRequest::DependencyUpdated:
1030+
sourcekitd_request_dictionary_set_uid(Req, KeyRequest,
1031+
RequestDependencyUpdated);
1032+
break;
10281033
}
10291034

10301035
if (!SourceFile.empty()) {
@@ -1223,6 +1228,7 @@ static bool handleResponse(sourcekitd_response_t Resp, const TestOptions &Opts,
12231228
case SourceKitRequest::CodeCompleteSetPopularAPI:
12241229
case SourceKitRequest::TypeContextInfo:
12251230
case SourceKitRequest::ConformingMethodList:
1231+
case SourceKitRequest::DependencyUpdated:
12261232
sourcekitd_response_description_dump_filedesc(Resp, STDOUT_FILENO);
12271233
break;
12281234

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -574,6 +574,11 @@ void handleRequestImpl(sourcekitd_object_t ReqObj, ResponseReceiver Rec) {
574574
return Rec(ResponseBuilder().createResponse());
575575
}
576576

577+
if (ReqUID == RequestDependencyUpdated) {
578+
getGlobalContext().getSwiftLangSupport().dependencyUpdated();
579+
return Rec(ResponseBuilder().createResponse());
580+
}
581+
577582
Optional<StringRef> SourceFile = Req.getString(KeySourceFile);
578583
Optional<StringRef> SourceText = Req.getString(KeySourceText);
579584

0 commit comments

Comments
 (0)