@@ -1240,30 +1240,61 @@ bool ASTBuildOperation::addConsumer(SwiftASTConsumerRef Consumer) {
1240
1240
return true ;
1241
1241
}
1242
1242
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
1243
1250
ASTBuildOperationRef ASTProducer::getBuildOperationForConsumer (
1244
1251
SwiftASTConsumerRef Consumer,
1245
1252
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FileSystem,
1246
1253
SwiftASTManagerRef Mgr) {
1254
+ ASTBuildOperationRef LatestUsableOp;
1255
+ Statistic *StatCount = nullptr ;
1247
1256
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 ;
1249
1273
continue ;
1250
1274
}
1275
+
1276
+ // Check for whether the operation can be used taking into account
1277
+ // snapshots
1251
1278
std::vector<ImmutableTextSnapshotRef> Snapshots;
1252
1279
Snapshots.reserve (BuildOp->getFileContents ().size ());
1253
1280
for (auto &FileContent : BuildOp->getFileContents ()) {
1254
1281
if (FileContent.Snapshot ) {
1255
1282
Snapshots.push_back (FileContent.Snapshot );
1256
1283
}
1257
1284
}
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 ;
1264
1291
}
1265
1292
}
1266
- return nullptr ;
1293
+
1294
+ if (StatCount) {
1295
+ ++(*StatCount);
1296
+ }
1297
+ return LatestUsableOp;
1267
1298
}
1268
1299
1269
1300
void ASTProducer::enqueueConsumer (
0 commit comments