diff --git a/rustparsejob.cpp b/rustparsejob.cpp index 8bee8f8..e2b45d0 100644 --- a/rustparsejob.cpp +++ b/rustparsejob.cpp @@ -1,115 +1,142 @@ #include "rustparsejob.h" #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; } 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)); } session.parse(); - RustOwnedNode crateNode = RustOwnedNode(node_from_crate(session.crate())); - RustNode node(crateNode); + ReferencedTopDUContext context; - DeclarationBuilder builder; - auto context = builder.build(document(), &node, toUpdate); + if (session.crate() != nullptr) { + qCDebug(KDEV_RUST) << "Parsing succeeded for: " << document().toUrl(); + RustOwnedNode crateNode = RustOwnedNode(node_from_crate(session.crate())); + RustNode node(crateNode); - setDuChain(context); + DeclarationBuilder builder; + context = builder.build(document(), &node, toUpdate); - UseBuilder uses; - uses.buildUses(&node); + setDuChain(context); - if (abortRequested()) { - return; - } + UseBuilder uses; + uses.buildUses(&node); - if (context) { - if (minimumFeatures() & TopDUContext::AST) { - DUChainWriteLocker lock; - context->setAst(IAstContainer::Ptr(session.data())); + if (abortRequested()) { + return; } highlightDUChain(); + + } 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); } + + // TODO: add problems exposed by libsyntax + + if (minimumFeatures() & TopDUContext::AST) { + DUChainWriteLocker lock; + context->setAst(IAstContainer::Ptr(session.data())); + } + + DUChain::self()->emitUpdateReady(document(), duChain()); qCDebug(KDEV_RUST) << "Parse job finished for: " << document().toUrl(); } }