Skip to content

Commit 7a80034

Browse files
committed
[SourceKit] Support cancellation of requests while an AST is being built
This commit refactors the way ASTs are being built in SourceKit and how `SwiftASTConsumer`s are served by the built ASTs. `SwiftASTManager.h` should give an overview of the new design. This commit does not change the cancellation paradigm in SourceKit (yet). That is, subsequent requests with the same `OncePerASTToken` still cancel previous requests with the same token. But while previously, we were only able to cancel requests that haven’t started an AST build yet, we can now also cancel the AST build of the to-be-cancelled requests. With this change in place, we can start looking into explicit cancellation of requests or other cancellation paradigms.
1 parent 998a787 commit 7a80034

File tree

6 files changed

+795
-247
lines changed

6 files changed

+795
-247
lines changed

include/swift/Basic/LangOptions.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,7 @@ namespace swift {
599599
/// typechecking should be aborted at the next possible opportunity.
600600
/// This is used by SourceKit to cancel requests for which the result is no
601601
/// longer of interest.
602-
std::shared_ptr<bool> CancellationFlag = nullptr;
602+
std::shared_ptr<std::atomic<bool>> CancellationFlag = nullptr;
603603

604604
/// If non-zero, abort the switch statement exhaustiveness checker if
605605
/// the Space::minus function is called more than this many times.

include/swift/Sema/ConstraintSystem.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -5156,7 +5156,7 @@ class ConstraintSystem {
51565156
return true;
51575157

51585158
auto CancellationFlag = getASTContext().TypeCheckerOpts.CancellationFlag;
5159-
if (CancellationFlag && *CancellationFlag)
5159+
if (CancellationFlag && CancellationFlag->load(std::memory_order_relaxed))
51605160
return true;
51615161

51625162
auto used = getASTContext().getSolverMemory() + solutionMemory;

test/SourceKit/Misc/stats.swift

+13-2
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ func foo() {}
4646
// SEMA_3: 1 {{.*}} source.statistic.num-ast-builds
4747
// SEMA_3: 1 {{.*}} source.statistic.num-asts-in-memory
4848
// SEMA_3: 1 {{.*}} source.statistic.max-asts-in-memory
49-
// SEMA_3: 0 {{.*}} source.statistic.num-ast-cache-hits
50-
// SEMA_3: 1 {{.*}} source.statistic.num-ast-snaphost-uses
49+
// SEMA_3: 1 {{.*}} source.statistic.num-ast-cache-hits
50+
// SEMA_3: 0 {{.*}} source.statistic.num-ast-snaphost-uses
5151

5252
// RUN: %sourcekitd-test -req=sema %s -- -Xfrontend -disable-implicit-concurrency-module-import %s == -req=related-idents -pos=1:6 %s -- -Xfrontend -disable-implicit-concurrency-module-import %s == -req=stats | %FileCheck %s -check-prefix=SEMA_4
5353

@@ -58,3 +58,14 @@ func foo() {}
5858
// SEMA_4: 1 {{.*}} source.statistic.max-asts-in-memory
5959
// SEMA_4: 1 {{.*}} source.statistic.num-ast-cache-hits
6060
// SEMA_4: 0 {{.*}} source.statistic.num-ast-snaphost-uses
61+
62+
// Test that we can have two files open and don't need to rebuild an AST when doing the cursor info request on '%s' after opening '10bytes.swift'
63+
// RUN: %sourcekitd-test \
64+
// RUN: -req=sema %s -- -Xfrontend -disable-implicit-concurrency-module-import %s == \
65+
// RUN: -req=sema %S/Inputs/10bytes.swift -- -Xfrontend -disable-implicit-concurrency-module-import %S/Inputs/10bytes.swift == \
66+
// RUN: -req=cursor -pos=1:6 %s -- -Xfrontend -disable-implicit-concurrency-module-import %s == \
67+
// RUN: -req=stats | %FileCheck %s -check-prefix=OPEN_TWO_FILES
68+
69+
// OPEN_TWO_FILES: 2 {{.*}} source.statistic.num-ast-builds
70+
// OPEN_TWO_FILES: 2 {{.*}} source.statistic.num-asts-in-memory
71+
// OPEN_TWO_FILES: 2 {{.*}} source.statistic.max-asts-in-memory

0 commit comments

Comments
 (0)