File indexing completed on 2024-05-12 04:39:26
0001 /* 0002 SPDX-FileCopyrightText: 2014 Aleix Pol <aleixpol@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "cmakeparsejob.h" 0008 #include "declarationbuilder.h" 0009 #include "usebuilder.h" 0010 #include <debug.h> 0011 #include <cmakelistsparser.h> 0012 #include <cmakemanager.h> 0013 #include <language/backgroundparser/urlparselock.h> 0014 #include <language/duchain/duchain.h> 0015 #include <language/duchain/duchainlock.h> 0016 #include <language/duchain/duchainutils.h> 0017 #include <interfaces/icore.h> 0018 #include <language/duchain/problem.h> 0019 0020 #include <KIO/Global> 0021 0022 #include <QReadWriteLock> 0023 0024 using namespace KDevelop; 0025 0026 CMakeParseJob::CMakeParseJob(const KDevelop::IndexedString& url, KDevelop::ILanguageSupport* languageSupport) 0027 : ParseJob(url, languageSupport) 0028 { 0029 } 0030 0031 IndexedString parentCMakeFile(const IndexedString& doc) 0032 { 0033 return IndexedString(QUrl(KIO::upUrl(doc.toUrl().adjusted(QUrl::RemoveFilename)).toString()+QLatin1String("CMakeLists.txt"))); 0034 } 0035 0036 void CMakeParseJob::run(ThreadWeaver::JobPointer /*self*/, ThreadWeaver::Thread* /*thread*/) 0037 { 0038 const IndexedString languageName(CMakeManager::languageName()); 0039 0040 UrlParseLock urlLock(document()); 0041 if (abortRequested() || !isUpdateRequired(languageName)) { 0042 return; 0043 } 0044 0045 ProblemPointer p = readContents(); 0046 if (p) { 0047 //TODO: associate problem with topducontext 0048 return; 0049 } 0050 0051 ReferencedTopDUContext parentCtx; 0052 if (document().str().endsWith(QLatin1String("CMakeLists.txt"))) { 0053 IndexedString parentFile = parentCMakeFile(document()); 0054 if (QFile::exists(parentFile.toUrl().toLocalFile())) { 0055 0056 // TODO: figure out includes import 0057 { 0058 DUChainReadLocker lock; 0059 parentCtx = DUChain::self()->chainForDocument(parentFile); 0060 } 0061 0062 if (!parentCtx) { 0063 qCDebug(CMAKE) << "waiting for..." << parentFile << document(); 0064 //FIXME: Currently dead-locks 0065 //parentCtx = DUChain::self()->waitForUpdate(parentFile, TopDUContext::AllDeclarationsAndContexts); 0066 } 0067 //Q_ASSERT(parentCtx); 0068 } 0069 } 0070 0071 ReferencedTopDUContext context; 0072 { 0073 DUChainReadLocker lock; 0074 context = DUChainUtils::standardContextForUrl(document().toUrl()); 0075 } 0076 if (context) { 0077 translateDUChainToRevision(context); 0078 0079 DUChainWriteLocker lock; 0080 context->setRange(RangeInRevision(0, 0, INT_MAX, INT_MAX)); 0081 context->addImportedParentContext(parentCtx); 0082 } 0083 0084 CMakeFileContent package = CMakeListsParser::readCMakeFile(document().toUrl().toLocalFile()); 0085 if (!package.isEmpty()) { 0086 if (abortRequested()) { 0087 abortJob(); 0088 return; 0089 } 0090 0091 QReadLocker parseLock(languageSupport()->parseLock()); 0092 CMakeContentIterator it(package); 0093 DeclarationBuilder builder; 0094 context = builder.build(document(), &it, context); 0095 0096 if (abortRequested()) { 0097 abortJob(); 0098 return; 0099 } 0100 0101 // session.reparseImporters(context); 0102 0103 if ( context && (minimumFeatures() & TopDUContext::AllDeclarationsContextsAndUses) ) { 0104 UseBuilder useBuilder(context); 0105 CMakeContentIterator it(package); 0106 useBuilder.startVisiting(&it); 0107 } 0108 } 0109 0110 if (abortRequested()) { 0111 abortJob(); 0112 return; 0113 } 0114 0115 if (!context) { 0116 DUChainWriteLocker lock; 0117 auto* file = new ParsingEnvironmentFile(document()); 0118 file->setLanguage(languageName); 0119 context = new TopDUContext(document(), RangeInRevision(0, 0, INT_MAX, INT_MAX), file); 0120 DUChain::self()->addDocumentChain(context); 0121 } 0122 0123 setDuChain(context); 0124 { 0125 DUChainWriteLocker lock; 0126 // context->setProblems(session.problems()); 0127 0128 context->setFeatures(minimumFeatures()); 0129 ParsingEnvironmentFilePointer file = context->parsingEnvironmentFile(); 0130 Q_ASSERT(file); 0131 file->setModificationRevision(contents().modification); 0132 DUChain::self()->updateContextEnvironment( context->topContext(), file.data() ); 0133 } 0134 highlightDUChain(); 0135 0136 DUChain::self()->emitUpdateReady(document(), duChain()); 0137 } 0138 0139 #include "moc_cmakeparsejob.cpp"