@@ -1219,30 +1219,61 @@ bool ASTBuildOperation::addConsumer(SwiftASTConsumerRef Consumer) {
1219
1219
return true ;
1220
1220
}
1221
1221
1222
+ // / Returns a build operation that `Consumer` can use, in order of the
1223
+ // / following:
1224
+ // / 1. The latest finished build operation that either exactly matches, or
1225
+ // / can be used with snapshots
1226
+ // / 2. If none, the latest in-progress build operation with the same
1227
+ // / conditions
1228
+ // / 3. `nullptr` otherwise
1222
1229
ASTBuildOperationRef ASTProducer::getBuildOperationForConsumer (
1223
1230
SwiftASTConsumerRef Consumer,
1224
1231
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
1225
1232
SwiftASTManagerRef Mgr) {
1233
+ ASTBuildOperationRef LatestUsableOp;
1234
+ Statistic *StatCount = nullptr ;
1226
1235
for (auto &BuildOp : llvm::reverse (BuildOperations)) {
1227
- if (BuildOp->isCancelled ()) {
1236
+ if (BuildOp->isCancelled ())
1237
+ continue ;
1238
+
1239
+ // No point checking for a match, we already have one - we're just looking
1240
+ // for a finished operation that can be used with the file contents of
1241
+ // `BuildOp` at this point (which we will prefer over an incomplete
1242
+ // operation, whether that exactly matches or not).
1243
+ if (LatestUsableOp && !BuildOp->isFinished ())
1244
+ continue ;
1245
+
1246
+ // Check for an exact match
1247
+ if (BuildOp->matchesSourceState (FileSystem)) {
1248
+ LatestUsableOp = BuildOp;
1249
+ StatCount = &Mgr->Impl .Stats ->numASTCacheHits ;
1250
+ if (BuildOp->isFinished ())
1251
+ break ;
1228
1252
continue ;
1229
1253
}
1254
+
1255
+ // Check for whether the operation can be used taking into account
1256
+ // snapshots
1230
1257
std::vector<ImmutableTextSnapshotRef> Snapshots;
1231
1258
Snapshots.reserve (BuildOp->getFileContents ().size ());
1232
1259
for (auto &FileContent : BuildOp->getFileContents ()) {
1233
1260
if (FileContent.Snapshot ) {
1234
1261
Snapshots.push_back (FileContent.Snapshot );
1235
1262
}
1236
1263
}
1237
- if (BuildOp-> matchesSourceState (FileSystem)) {
1238
- ++Mgr-> Impl . Stats -> numASTCacheHits ;
1239
- return BuildOp;
1240
- } else if (Consumer-> canUseASTWithSnapshots (Snapshots)) {
1241
- ++Mgr-> Impl . Stats -> numASTsUsedWithSnapshots ;
1242
- return BuildOp ;
1264
+
1265
+ if (Consumer-> canUseASTWithSnapshots (Snapshots)) {
1266
+ LatestUsableOp = BuildOp;
1267
+ StatCount = &Mgr-> Impl . Stats -> numASTsUsedWithSnapshots ;
1268
+ if (BuildOp-> isFinished ())
1269
+ break ;
1243
1270
}
1244
1271
}
1245
- return nullptr ;
1272
+
1273
+ if (StatCount) {
1274
+ ++(*StatCount);
1275
+ }
1276
+ return LatestUsableOp;
1246
1277
}
1247
1278
1248
1279
void ASTProducer::enqueueConsumer (
0 commit comments