void SwiftASTManager::processASTAsync(SwiftInvocationRef InvokRef, SwiftASTConsumerRef ASTConsumer, const void *OncePerASTToken, ArrayRef<ImmutableTextSnapshotRef> Snapshots) { ASTProducerRef Producer = Impl.getASTProducer(InvokRef); if (ASTUnitRef Unit = Producer->getExistingAST()) { if (ASTConsumer->canUseASTWithSnapshots(Unit->getSnapshots())) { Unit->Impl.consumeAsync(std::move(ASTConsumer), Unit); return; } } Producer->enqueueConsumer(std::move(ASTConsumer), OncePerASTToken); Producer->getASTUnitAsync(Impl, Snapshots, [Producer](ASTUnitRef Unit, StringRef Error) { auto Consumers = Producer->popQueuedConsumers(); for (auto &Consumer : Consumers) { if (Unit) Unit->Impl.consumeAsync(std::move(Consumer), Unit); else Consumer->failed(Error); } }); }
void ASTProducer::getASTUnitAsync(SwiftASTManager::Implementation &MgrImpl, ArrayRef<ImmutableTextSnapshotRef> Snaps, std::function<void(ASTUnitRef Unit, StringRef Error)> Receiver) { ASTProducerRef ThisProducer = this; SmallVector<ImmutableTextSnapshotRef, 4> Snapshots; Snapshots.append(Snaps.begin(), Snaps.end()); MgrImpl.ASTBuildQueue.dispatch([ThisProducer, &MgrImpl, Snapshots, Receiver] { std::string Error; ASTUnitRef Unit = ThisProducer->getASTUnitImpl(MgrImpl, Snapshots, Error); Receiver(Unit, Error); }, /*isStackDeep=*/true); }
void SwiftASTManager::processASTAsync(SwiftInvocationRef InvokRef, SwiftASTConsumerRef ASTConsumer, const void *OncePerASTToken, ArrayRef<ImmutableTextSnapshotRef> Snapshots) { ASTProducerRef Producer = Impl.getASTProducer(InvokRef); if (ASTUnitRef Unit = Producer->getExistingAST()) { if (ASTConsumer->canUseASTWithSnapshots(Unit->getSnapshots())) { ++Impl.Stats.numASTsUsedWithSnaphots; Unit->Impl.consumeAsync(std::move(ASTConsumer), Unit); return; } } Producer->enqueueConsumer(ASTConsumer, Snapshots, OncePerASTToken); auto handleAST = [this, Producer, ASTConsumer](ASTUnitRef unit, StringRef error) { auto consumers = Producer->takeConsumers( [&](SwiftASTConsumer *consumer, ArrayRef<ImmutableTextSnapshotRef> snapshots) { return consumer == ASTConsumer.get() || !Producer->shouldRebuild(Impl, snapshots) || (unit && consumer->canUseASTWithSnapshots(snapshots)); }); for (auto &consumer : consumers) { if (unit) unit->Impl.consumeAsync(std::move(consumer), unit); else consumer->failed(error); } }; Producer->getASTUnitAsync(Impl, Snapshots, std::move(handleAST)); }