Skip to content

Commit 1d7c534

Browse files
authored
Merge pull request #66839 from bnbarham/reuse-cursor-ast
[CursorInfo] Re-use already built ASTs ahead of currently building ones
2 parents 9a11e04 + 037ddc9 commit 1d7c534

File tree

2 files changed

+42
-9
lines changed

2 files changed

+42
-9
lines changed

test/SourceKit/CursorInfo/cursor_after_edit.swift

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,6 @@
88
// RUN: %sourcekitd-test \
99
// RUN: -req=open -text-input %t/empty.swift %t/func.swift -- %t/func.swift == \
1010
// RUN: -req=edit -offset=0 -length=0 -replace="func foo() {}" -req-opts=enablesyntaxmap=0,enablesubstructure=0,enablediagnostics=0 %t/func.swift -- %t/func.swift == \
11-
// RUN: -req=cursor -offset=5 %t/func.swift -- %t/func.swift
11+
// RUN: -req=cursor -offset=5 %t/func.swift -- %t/func.swift == \
12+
// RUN: -req=edit -offset=0 -length=0 -replace="// some comment\n" -req-opts=enablesyntaxmap=0,enablesubstructure=0,enablediagnostics=0 %t/func.swift -- %t/func.swift == \
13+
// RUN: -req=cursor -offset=21 %t/func.swift -- %t/func.swift

tools/SourceKit/lib/SwiftLang/SwiftASTManager.cpp

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1240,30 +1240,61 @@ bool ASTBuildOperation::addConsumer(SwiftASTConsumerRef Consumer) {
12401240
return true;
12411241
}
12421242

1243+
/// Returns a build operation that `Consumer` can use, in order of the
1244+
/// following:
1245+
/// 1. The latest finished build operation that either exactly matches, or
1246+
/// can be used with snapshots
1247+
/// 2. If none, the latest in-progress build operation with the same
1248+
/// conditions
1249+
/// 3. `nullptr` otherwise
12431250
ASTBuildOperationRef ASTProducer::getBuildOperationForConsumer(
12441251
SwiftASTConsumerRef Consumer,
12451252
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
12461253
SwiftASTManagerRef Mgr) {
1254+
ASTBuildOperationRef LatestUsableOp;
1255+
Statistic *StatCount = nullptr;
12471256
for (auto &BuildOp : llvm::reverse(BuildOperations)) {
1248-
if (BuildOp->isCancelled()) {
1257+
if (BuildOp->isCancelled())
1258+
continue;
1259+
1260+
// No point checking for a match, we already have one - we're just looking
1261+
// for a finished operation that can be used with the file contents of
1262+
// `BuildOp` at this point (which we will prefer over an incomplete
1263+
// operation, whether that exactly matches or not).
1264+
if (LatestUsableOp && !BuildOp->isFinished())
1265+
continue;
1266+
1267+
// Check for an exact match
1268+
if (BuildOp->matchesSourceState(FileSystem)) {
1269+
LatestUsableOp = BuildOp;
1270+
StatCount = &Mgr->Impl.Stats->numASTCacheHits;
1271+
if (BuildOp->isFinished())
1272+
break;
12491273
continue;
12501274
}
1275+
1276+
// Check for whether the operation can be used taking into account
1277+
// snapshots
12511278
std::vector<ImmutableTextSnapshotRef> Snapshots;
12521279
Snapshots.reserve(BuildOp->getFileContents().size());
12531280
for (auto &FileContent : BuildOp->getFileContents()) {
12541281
if (FileContent.Snapshot) {
12551282
Snapshots.push_back(FileContent.Snapshot);
12561283
}
12571284
}
1258-
if (BuildOp->matchesSourceState(FileSystem)) {
1259-
++Mgr->Impl.Stats->numASTCacheHits;
1260-
return BuildOp;
1261-
} else if (Consumer->canUseASTWithSnapshots(Snapshots)) {
1262-
++Mgr->Impl.Stats->numASTsUsedWithSnapshots;
1263-
return BuildOp;
1285+
1286+
if (Consumer->canUseASTWithSnapshots(Snapshots)) {
1287+
LatestUsableOp = BuildOp;
1288+
StatCount = &Mgr->Impl.Stats->numASTsUsedWithSnapshots;
1289+
if (BuildOp->isFinished())
1290+
break;
12641291
}
12651292
}
1266-
return nullptr;
1293+
1294+
if (StatCount) {
1295+
++(*StatCount);
1296+
}
1297+
return LatestUsableOp;
12671298
}
12681299

12691300
void ASTProducer::enqueueConsumer(

0 commit comments

Comments
 (0)