diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 4895e66331a..994431c24f6 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -636,12 +636,33 @@ QSet QmakePriFileNode::recursiveEnumerate(const QString &folder) return result; } -PriFileEvalResult QmakePriFileNode::extractValues(const EvalInput &input, - ProFile *proFile, bool haveExact, - const QList> &variableAndVPathInformation) +QStringList QmakeProFileNode::fileListForVar( + const QHash > &sourceFiles, + const QString &varName) { - PriFileEvalResult result; + const QVector &sources = sourceFiles[varName]; + QStringList result; + result.reserve(sources.size()); + foreach (const ProFileEvaluator::SourceFile &sf, sources) + result << sf.fileName; + return result; +} +void QmakePriFileNode::extractSources( + QHash proToResult, PriFileEvalResult *fallback, + QVector sourceFiles, FileType type) +{ + foreach (const ProFileEvaluator::SourceFile &source, sourceFiles) { + PriFileEvalResult *result = proToResult.value(source.proFile); + if (!result) + result = fallback; + result->foundFiles[type].insert(FileName::fromString(source.fileName)); + } +} + +void QmakePriFileNode::extractValues( + const EvalInput &input, ProFile *proFile, PriFileEvalResult &result) +{ // Figure out DEPLOYMENT and INSTALL folders. // Ignore stuff from cumulative parse, as we are recursively enumerating // all the files from those folders and add watchers for them. That's too @@ -682,40 +703,14 @@ PriFileEvalResult QmakePriFileNode::extractValues(const EvalInput &input, result.recursiveEnumerateFiles += recursiveEnumerate(folder); const QVector &fileTypes = qmakeNodeStaticData()->fileTypeData; - // update files for (int i = 0; i < fileTypes.size(); ++i) { FileType type = fileTypes.at(i).type; - const QList &qmakeVariables = variableAndVPathInformation.at(i); - QSet newFilePaths; - foreach (const VariableAndVPathInformation &qmakeVariable, qmakeVariables) { - if (haveExact) { - QStringList tmp = input.readerExact->absoluteFileValues( - qmakeVariable.variable, input.projectDir, qmakeVariable.vPathsExact, proFile); - foreach (const QString &t, tmp) - newFilePaths += FileName::fromString(t); - } - { - QStringList tmp = input.readerCumulative->absoluteFileValues( - qmakeVariable.variable, input.projectDir, qmakeVariable.vPathsCumulative, proFile); - foreach (const QString &t, tmp) - newFilePaths += FileName::fromString(t); - } - } - - result.foundFiles[type] = newFilePaths; - result.recursiveEnumerateFiles.subtract(newFilePaths); - } - - - for (int i = 0; i < fileTypes.size(); ++i) { - FileType type = fileTypes.at(i).type; - QSet newFilePaths = filterFilesProVariables(type, result.foundFiles[type]); + QSet &foundFiles = result.foundFiles[type]; + result.recursiveEnumerateFiles.subtract(foundFiles); + QSet newFilePaths = filterFilesProVariables(type, foundFiles); newFilePaths += filterFilesRecursiveEnumerata(type, result.recursiveEnumerateFiles); - result.foundFiles[type] = newFilePaths; + foundFiles = newFilePaths; } - - - return result; } void QmakePriFileNode::update(const Internal::PriFileEvalResult &result) @@ -1850,6 +1845,8 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) result->includedFiles.proFile = pro; result->includedFiles.name = input.projectFilePath; + QHash proToResult; + result->projectType = proFileTemplateTypeToProjectType( (result->state == EvalResult::EvalOk ? input.readerExact : input.readerCumulative)->templateType()); @@ -1883,6 +1880,7 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) childTree->proFile = child; childTree->name = childName; current->children.insert(childName, childTree); + proToResult[child] = &childTree->result; } } toBuild.append(current->children.values()); @@ -1916,6 +1914,7 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) childTree->proFile = child; childTree->name = childName; current->children.insert(childName, childTree); + proToResult[child] = &childTree->result; } } toBuild.append(current->children.values()); @@ -1924,6 +1923,34 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) auto exactReader = exactBuildPassReader ? exactBuildPassReader : input.readerExact; auto cumulativeReader = cumulativeBuildPassReader ? cumulativeBuildPassReader : input.readerCumulative; + QHash > exactSourceFiles; + QHash > cumulativeSourceFiles; + + QStringList baseVPathsExact = baseVPaths(exactReader, input.projectDir, input.buildDirectory); + QStringList baseVPathsCumulative = baseVPaths(cumulativeReader, input.projectDir, input.buildDirectory); + + const QVector &fileTypes = qmakeNodeStaticData()->fileTypeData; + for (int i = 0; i < fileTypes.size(); ++i) { + FileType type = fileTypes.at(i).type; + QStringList qmakeVariables = varNames(type, exactReader); + foreach (const QString &qmakeVariable, qmakeVariables) { + if (result->state == EvalResult::EvalOk) { + QStringList vPathsExact = fullVPaths( + baseVPathsExact, exactReader, qmakeVariable, input.projectDir); + auto sourceFiles = exactReader->absoluteFileValues( + qmakeVariable, input.projectDir, vPathsExact); + exactSourceFiles[qmakeVariable] = sourceFiles; + extractSources(proToResult, &result->includedFiles.result, sourceFiles, type); + } + QStringList vPathsCumulative = fullVPaths( + baseVPathsCumulative, cumulativeReader, qmakeVariable, input.projectDir); + auto sourceFiles = cumulativeReader->absoluteFileValues( + qmakeVariable, input.projectDir, vPathsCumulative); + cumulativeSourceFiles[qmakeVariable] = sourceFiles; + extractSources(proToResult, &result->includedFiles.result, sourceFiles, type); + } + } + if (result->state == EvalResult::EvalOk) { result->targetInformation = targetInformation(input.readerExact, exactBuildPassReader, input.buildDirectory, input.projectFilePath.toString()); @@ -1935,21 +1962,21 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) result->newVarValues[IncludePathVar] = includePaths(exactReader, input.sysroot, input.buildDirectory, input.projectDir); result->newVarValues[CppFlagsVar] = exactReader->values(QLatin1String("QMAKE_CXXFLAGS")); - result->newVarValues[SourceVar] = - fileListForVar(exactReader, cumulativeReader, - QLatin1String("SOURCES"), input.projectDir, input.buildDirectory) + - fileListForVar(exactReader, cumulativeReader, - QLatin1String("HEADERS"), input.projectDir, input.buildDirectory) + - fileListForVar(exactReader, cumulativeReader, - QLatin1String("OBJECTIVE_HEADERS"), input.projectDir, input.buildDirectory); + QStringList allSources = + fileListForVar(exactSourceFiles, QLatin1String("SOURCES")) + + fileListForVar(cumulativeSourceFiles, QLatin1String("SOURCES")) + + fileListForVar(exactSourceFiles, QLatin1String("HEADERS")) + + fileListForVar(cumulativeSourceFiles, QLatin1String("HEADERS")) + + fileListForVar(exactSourceFiles, QLatin1String("OBJECTIVE_HEADERS")) + + fileListForVar(cumulativeSourceFiles, QLatin1String("OBJECTIVE_HEADERS")); + allSources.removeDuplicates(); + result->newVarValues[SourceVar] = allSources; result->newVarValues[UiDirVar] = QStringList() << uiDirPath(exactReader, input.buildDirectory); result->newVarValues[HeaderExtensionVar] = QStringList() << exactReader->value(QLatin1String("QMAKE_EXT_H")); result->newVarValues[CppExtensionVar] = QStringList() << exactReader->value(QLatin1String("QMAKE_EXT_CPP")); result->newVarValues[MocDirVar] = QStringList() << mocDirPath(exactReader, input.buildDirectory); - result->newVarValues[ExactResourceVar] = fileListForVar(exactReader, 0, - QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory); - result->newVarValues[CumulativeResourceVar] = fileListForVar(cumulativeReader, 0, - QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory); + result->newVarValues[ExactResourceVar] = fileListForVar(exactSourceFiles, QLatin1String("RESOURCES")); + result->newVarValues[CumulativeResourceVar] = fileListForVar(cumulativeSourceFiles, QLatin1String("RESOURCES")); result->newVarValues[PkgConfigVar] = exactReader->values(QLatin1String("PKGCONFIG")); result->newVarValues[PrecompiledHeaderVar] = exactReader->fixifiedValues( QLatin1String("PRECOMPILED_HEADER"), input.projectDir, input.buildDirectory); @@ -1981,37 +2008,11 @@ EvalResult *QmakeProFileNode::evaluate(const EvalInput &input) if (result->state == EvalResult::EvalOk || result->state == EvalResult::EvalPartial) { - QList> variableAndVPathInformation; - { // Collect information on VPATHS and qmake variables - QStringList baseVPathsExact = baseVPaths(exactReader, input.projectDir, input.buildDirectory); - QStringList baseVPathsCumulative = baseVPaths(cumulativeReader, input.projectDir, input.buildDirectory); - - const QVector &fileTypes = qmakeNodeStaticData()->fileTypeData; - - variableAndVPathInformation.reserve(fileTypes.size()); - for (int i = 0; i < fileTypes.size(); ++i) { - FileType type = fileTypes.at(i).type; - - QList list; - QStringList qmakeVariables = varNames(type, exactReader); - list.reserve(qmakeVariables.size()); - foreach (const QString &qmakeVariable, qmakeVariables) { - VariableAndVPathInformation info; - info.variable = qmakeVariable; - info.vPathsExact = fullVPaths(baseVPathsExact, exactReader, qmakeVariable, input.projectDir); - info.vPathsCumulative = fullVPaths(baseVPathsCumulative, cumulativeReader, qmakeVariable, input.projectDir); - list.append(info); - } - variableAndVPathInformation.append(list); - } - } - // extract values for each .pri file and add it to IncludedPriFiles structure QList toExtract = { &result->includedFiles }; while (!toExtract.isEmpty()) { IncludedPriFile *current = toExtract.takeFirst(); - current->result = extractValues(input, current->proFile, (result->state == EvalResult::EvalOk), - variableAndVPathInformation); + extractValues(input, current->proFile, current->result); toExtract.append(current->children.values()); } } @@ -2254,29 +2255,6 @@ void QmakeProFileNode::cleanupProFileReaders() m_readerCumulative = nullptr; } -QStringList QmakeProFileNode::fileListForVar(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative, - const QString &varName, const QString &projectDir, const QString &buildDir) -{ - QStringList baseVPathsExact = baseVPaths(readerExact, projectDir, buildDir); - QStringList vPathsExact = fullVPaths(baseVPathsExact, readerExact, varName, projectDir); - - QStringList result; - result = readerExact->absoluteFileValues(varName, - projectDir, - vPathsExact, - 0); - if (readerCumulative) { - QStringList baseVPathsCumulative = baseVPaths(readerCumulative, projectDir, buildDir); - QStringList vPathsCumulative = fullVPaths(baseVPathsCumulative, readerCumulative, varName, projectDir); - result += readerCumulative->absoluteFileValues(varName, - projectDir, - vPathsCumulative, - 0); - } - result.removeDuplicates(); - return result; -} - QString QmakeProFileNode::uiDirPath(QtSupport::ProFileReader *reader, const QString &buildDir) { QString path = reader->value(QLatin1String("UI_DIR")); diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index 3f981395486..66e2d167d36 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -27,6 +27,7 @@ #include "qmakeprojectmanager_global.h" #include "proparser/prowriter.h" +#include "proparser/profileevaluator.h" #include #include @@ -38,11 +39,6 @@ #include #include -// defined in proitems.h -QT_BEGIN_NAMESPACE -class ProFile; -QT_END_NAMESPACE - namespace Utils { class FileName; } namespace Core { class ICore; } @@ -117,15 +113,6 @@ struct InternalNode; class EvalInput; class EvalResult; class PriFileEvalResult; -// TOOD can probably move into the .cpp file -class VariableAndVPathInformation -{ -public: - QString variable; - QStringList vPathsExact; - QStringList vPathsCumulative; -}; - } // Implements ProjectNode for qmake .pri files @@ -210,8 +197,12 @@ private: QStringList formResources(const QString &formFile) const; static QStringList baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir); static QStringList fullVPaths(const QStringList &baseVPaths, QtSupport::ProFileReader *reader, const QString &qmakeVariable, const QString &projectDir); - static Internal::PriFileEvalResult extractValues(const Internal::EvalInput &input, ProFile *proFile, bool haveExact, - const QList> &variableAndVPathInformation); + static void extractSources( + QHash proToResult, + Internal::PriFileEvalResult *fallback, + QVector sourceFiles, ProjectExplorer::FileType type); + static void extractValues( + const Internal::EvalInput &input, ProFile *proFile, Internal::PriFileEvalResult &result); void watchFolders(const QSet &folders); QmakeProject *m_project; @@ -387,8 +378,9 @@ private: void updateGeneratedFiles(const QString &buildDir); - static QStringList fileListForVar(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative, - const QString &varName, const QString &projectDir, const QString &buildDir); + static QStringList fileListForVar( + const QHash > &sourceFiles, + const QString &varName); static QString uiDirPath(QtSupport::ProFileReader *reader, const QString &buildDir); static QString mocDirPath(QtSupport::ProFileReader *reader, const QString &buildDir); static QString sysrootify(const QString &path, const QString &sysroot, const QString &baseDir, const QString &outputDir); diff --git a/src/shared/proparser/profileevaluator.cpp b/src/shared/proparser/profileevaluator.cpp index 995658cdd2d..2c179a2584a 100644 --- a/src/shared/proparser/profileevaluator.cpp +++ b/src/shared/proparser/profileevaluator.cpp @@ -119,17 +119,17 @@ QStringList ProFileEvaluator::absolutePathValues( return result; } -QStringList ProFileEvaluator::absoluteFileValues( - const QString &variable, const QString &baseDirectory, const QStringList &searchDirs, - const ProFile *pro) const +QVector ProFileEvaluator::absoluteFileValues( + const QString &variable, const QString &baseDirectory, const QStringList &searchDirs) const { QMakeVfs::VfsFlags flags = (d->m_cumulative ? QMakeVfs::VfsCumulative : QMakeVfs::VfsExact); - QStringList result; - foreach (const QString &el, pro ? values(variable, pro) : values(variable)) { + QVector result; + foreach (const ProString &str, d->values(ProKey(variable))) { + const QString &el = d->m_option->expandEnvVars(str.toQString()); QString absEl; if (IoUtils::isAbsolutePath(el)) { if (m_vfs->exists(el, flags)) { - result << el; + result << SourceFile{ el, str.sourceFile() }; goto next; } absEl = el; @@ -137,7 +137,7 @@ QStringList ProFileEvaluator::absoluteFileValues( foreach (const QString &dir, searchDirs) { QString fn = QDir::cleanPath(dir + QLatin1Char('/') + el); if (m_vfs->exists(fn, flags)) { - result << fn; + result << SourceFile{ QDir::cleanPath(fn), str.sourceFile() }; goto next; } } @@ -157,7 +157,7 @@ QStringList ProFileEvaluator::absoluteFileValues( theDir.setFilter(theDir.filter() & ~QDir::AllDirs); foreach (const QString &fn, theDir.entryList(QStringList(wildcard))) if (fn != QLatin1String(".") && fn != QLatin1String("..")) - result << absDir + QLatin1Char('/') + fn; + result << SourceFile{ absDir + QLatin1Char('/') + fn, str.sourceFile() }; } // else if (acceptMissing) } } diff --git a/src/shared/proparser/profileevaluator.h b/src/shared/proparser/profileevaluator.h index 898198e66be..c6d4a79cfae 100644 --- a/src/shared/proparser/profileevaluator.h +++ b/src/shared/proparser/profileevaluator.h @@ -53,6 +53,11 @@ public: TT_Subdirs }; + struct SourceFile { + QString fileName; + const ProFile *proFile; + }; + // Call this from a concurrency-free context static void initialize(); @@ -79,9 +84,8 @@ public: QStringList fixifiedValues( const QString &variable, const QString &baseDirectory, const QString &buildDirectory) const; QStringList absolutePathValues(const QString &variable, const QString &baseDirectory) const; - QStringList absoluteFileValues( - const QString &variable, const QString &baseDirectory, const QStringList &searchDirs, - const ProFile *pro) const; + QVector absoluteFileValues( + const QString &variable, const QString &baseDirectory, const QStringList &searchDirs) const; QString propertyValue(const QString &val) const; private: @@ -89,4 +93,6 @@ private: QMakeVfs *m_vfs; }; +Q_DECLARE_TYPEINFO(ProFileEvaluator::SourceFile, Q_MOVABLE_TYPE); + QT_END_NAMESPACE