diff --git a/rustparsejob.cpp b/rustparsejob.cpp index 849c291..a88ec1a 100644 --- a/rustparsejob.cpp +++ b/rustparsejob.cpp @@ -1,180 +1,188 @@ #include "rustparsejob.h" #include #include #include #include #include #include #include #include #include #include #include "duchain/parsesession.h" #include "duchain/astredux.h" #include "duchain/declarationbuilder.h" #include "duchain/usebuilder.h" #include "rustlanguagesupport.h" #include "rustdebug.h" using namespace KDevelop; namespace Rust { ParseJob::ParseJob(const IndexedString &url, ILanguageSupport *languageSupport) : KDevelop::ParseJob(url, languageSupport) { } LanguageSupport *ParseJob::rust() const { return static_cast(languageSupport()); } ParseSessionData::Ptr ParseJob::findParseSessionData(const IndexedString &url) { DUChainReadLocker lock; auto context = KDevelop::DUChainUtils::standardContextForUrl(url.toUrl()); if (context) { return ParseSessionData::Ptr(dynamic_cast(context->ast().data())); } return {}; } void ParseJob::run(ThreadWeaver::JobPointer self, ThreadWeaver::Thread *thread) { if (abortRequested() || ICore::self()->shuttingDown()) { return abortJob(); } qCDebug(KDEV_RUST) << "Parse job starting for: " << document().toUrl(); QReadLocker parseLock(languageSupport()->parseLock()); { UrlParseLock urlLock(document()); readContents(); } if (abortRequested()) { return; } if (!(minimumFeatures() & TopDUContext::ForceUpdate || minimumFeatures() & Rescheduled)) { DUChainReadLocker lock; static const IndexedString langString(rust()->name()); for (const ParsingEnvironmentFilePointer &file : DUChain::self()->allEnvironmentFiles(document())) { if (file->language() != langString) { continue; } if (!file->needsUpdate() && file->featuresSatisfied(minimumFeatures()) && file->topContext()) { qCDebug(KDEV_RUST) << "Already up to date, skipping:" << document().str(); setDuChain(file->topContext()); if (ICore::self()->languageController()->backgroundParser()->trackerForUrl(document())) { lock.unlock(); highlightDUChain(); } return; } break; } } if (abortRequested()) { return; } ParseSession session(findParseSessionData(document())); if (!session.data()) { session.setData(ParseSessionData::Ptr(new ParseSessionData(document(), contents().contents))); } if (abortRequested()) { return; } ReferencedTopDUContext toUpdate = nullptr; { DUChainReadLocker lock; toUpdate = DUChainUtils::standardContextForUrl(document().toUrl()); } if (toUpdate) { translateDUChainToRevision(toUpdate); toUpdate->setRange(RangeInRevision(0, 0, INT_MAX, INT_MAX)); toUpdate->clearProblems(); } session.parse(); RustOwnedNode crateNode = RustOwnedNode(node_from_crate(session.crate())); + if (abortRequested()) { + return; + } + ReferencedTopDUContext context; if (crateNode.data() != nullptr) { RustNode node(crateNode); qCDebug(KDEV_RUST) << "Parsing succeeded for: " << document().toUrl(); DeclarationBuilder builder; builder.setParseSession(&session); context = builder.build(document(), &node, toUpdate); setDuChain(context); - UseBuilder uses(document()); - uses.setParseSession(&session); - uses.buildUses(&node); - if (abortRequested()) { return; } + + UseBuilder uses(document()); + uses.setParseSession(&session); + uses.buildUses(&node); } else { qCDebug(KDEV_RUST) << "Parsing failed for: " << document().toUrl(); DUChainWriteLocker lock; context = toUpdate.data(); if (context) { ParsingEnvironmentFilePointer parsingEnvironmentFile = context->parsingEnvironmentFile(); parsingEnvironmentFile->setModificationRevision(contents().modification); context->clearProblems(); } else { ParsingEnvironmentFile *file = new ParsingEnvironmentFile(document()); file->setLanguage(IndexedString("Rust")); context = new TopDUContext(document(), RangeInRevision(0, 0, INT_MAX, INT_MAX), file); DUChain::self()->addDocumentChain(context); } setDuChain(context); } + if (abortRequested()) { + return; + } + // TODO: add problems exposed by libsyntax if (minimumFeatures() & TopDUContext::AST) { DUChainWriteLocker lock; context->setAst(IAstContainer::Ptr(session.data())); } { DUChainWriteLocker lock; context->setFeatures(minimumFeatures()); ParsingEnvironmentFilePointer file = context->parsingEnvironmentFile(); Q_ASSERT(file); file->setModificationRevision(contents().modification); DUChain::self()->updateContextEnvironment(context->topContext(), file.data()); } highlightDUChain(); DUChain::self()->emitUpdateReady(document(), duChain()); qCDebug(KDEV_RUST) << "Parse job finished for: " << document().toUrl(); } }