QmakeProject parsing: Move code from gui thread to parser threads

Change-Id: I05c1ec01a2c1ae4017ad2d09b07aa87854e3f118
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Daniel Teske
2014-09-10 12:53:55 +02:00
parent c61804679f
commit 679d4e3582
4 changed files with 438 additions and 292 deletions

View File

@@ -182,6 +182,54 @@ enum { debug = 0 };
using namespace QmakeProjectManager;
using namespace QmakeProjectManager::Internal;
namespace QmakeProjectManager {
namespace Internal {
class EvalInput
{
public:
QString projectDir;
QString projectFilePath;
QString buildDirectory;
QtSupport::ProFileReader *readerExact;
QtSupport::ProFileReader *readerCumulative;
ProFileGlobals *qmakeGlobals;
QMakeVfs *qmakeVfs;
bool isQt5;
};
class PriFileEvalResult
{
public:
QStringList folders;
QSet<Utils::FileName> recursiveEnumerateFiles;
QMap<FileType, QSet<Utils::FileName> > foundFiles;
};
class EvalResult
{
public:
enum EvalResultState { EvalAbort, EvalFail, EvalPartial, EvalOk };
EvalResultState state;
QmakeProjectType projectType;
QStringList subProjectsNotToDeploy;
QHash<QString, ProFile*> includeFilesExact;
QStringList newProjectFilesExact;
QSet<QString> exactSubdirs;
ProFile *fileForCurrentProjectExact; // probably only used in parser thread
QHash<QString, ProFile*> includeFilesCumlative;
QStringList newProjectFilesCumlative;
ProFile *fileForCurrentProjectCumlative; // probably only used in parser thread
TargetInformation targetInformation;
QString resolvedMkspecPath;
InstallsList installsList;
QHash<QmakeVariable, QStringList> newVarValues;
bool isDeployable;
QHash<QString, PriFileEvalResult> priFileResults;
QStringList errors;
};
}
}
QmakePriFile::QmakePriFile(QmakeProjectManager::QmakePriFileNode *qmakePriFile)
: IDocument(qmakePriFile), m_priFile(qmakePriFile)
{
@@ -545,7 +593,7 @@ struct InternalNode
};
}
QStringList QmakePriFileNode::baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir) const
QStringList QmakePriFileNode::baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir)
{
QStringList result;
if (!reader)
@@ -558,7 +606,7 @@ QStringList QmakePriFileNode::baseVPaths(QtSupport::ProFileReader *reader, const
}
QStringList QmakePriFileNode::fullVPaths(const QStringList &baseVPaths, QtSupport::ProFileReader *reader,
const QString &qmakeVariable, const QString &projectDir) const
const QString &qmakeVariable, const QString &projectDir)
{
QStringList vPaths;
if (!reader)
@@ -589,72 +637,54 @@ QSet<Utils::FileName> QmakePriFileNode::recursiveEnumerate(const QString &folder
return result;
}
void QmakePriFileNode::update(ProFile *includeFileExact, QtSupport::ProFileReader *readerExact,
ProFile *includeFileCumlative, QtSupport::ProFileReader *readerCumulative,
const QString &buildDir,
PriFileEvalResult QmakePriFileNode::extractValues(const EvalInput &input, ProFile *includeFileExact, ProFile *includeFileCumlative,
const QList<QList<VariableAndVPathInformation>> &variableAndVPathInformation)
{
// add project file node
if (m_fileNodes.isEmpty())
addFileNodes(QList<FileNode*>() << new ProjectExplorer::FileNode(m_projectFilePath, ProjectExplorer::ProjectFileType, false));
const QString &projectDir = m_qmakeProFileNode->m_projectDir;
InternalNode contents;
ProjectExplorer::Target *t = m_project->activeTarget();
ProjectExplorer::Kit *k = t ? t->kit() : ProjectExplorer::KitManager::defaultKit();
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
PriFileEvalResult result;
// Figure out DEPLOYMENT and INSTALL folders
QStringList folders;
QStringList dynamicVariables = dynamicVarNames(readerExact, readerCumulative, qtVersion);
QStringList dynamicVariables = dynamicVarNames(input.readerExact, input.readerCumulative, input.isQt5);
if (includeFileExact)
foreach (const QString &dynamicVar, dynamicVariables) {
folders += readerExact->values(dynamicVar, includeFileExact);
result.folders += input.readerExact->values(dynamicVar, includeFileExact);
// Ignore stuff from cumulative parse
// we are recursively enumerating all the files from those folders
// and add watchers for them, that's too dangerous if we get the foldrs
// and add watchers for them, that's too dangerous if we get the folders
// wrong and enumerate the whole project tree multiple times
}
for (int i=0; i < folders.size(); ++i) {
const QFileInfo fi(folders.at(i));
for (int i=0; i < result.folders.size(); ++i) {
const QFileInfo fi(result.folders.at(i));
if (fi.isRelative())
folders[i] = QDir::cleanPath(projectDir + QLatin1Char('/') + folders.at(i));
result.folders[i] = QDir::cleanPath(input.projectDir + QLatin1Char('/') + result.folders.at(i));
}
folders.removeDuplicates();
result.folders.removeDuplicates();
m_recursiveEnumerateFiles.clear();
// Remove non existing items and non folders
QStringList::iterator it = folders.begin();
while (it != folders.end()) {
QStringList::iterator it = result.folders.begin();
while (it != result.folders.end()) {
QFileInfo fi(*it);
if (fi.exists()) {
if (fi.isDir()) {
// keep directories
++it;
} else {
// move files directly to m_recursiveEnumerateFiles
m_recursiveEnumerateFiles << Utils::FileName::fromString(*it);
it = folders.erase(it);
// move files directly to recursiveEnumerateFiles
result.recursiveEnumerateFiles << Utils::FileName::fromString(*it);
it = result.folders.erase(it);
}
} else {
// do remove non exsting stuff
it = folders.erase(it);
it = result.folders.erase(it);
}
}
watchFolders(folders.toSet());
foreach (const QString &folder, result.folders)
result.recursiveEnumerateFiles += recursiveEnumerate(folder);
foreach (const QString &folder, folders) {
m_recursiveEnumerateFiles += recursiveEnumerate(folder);
}
QMap<FileType, QSet<Utils::FileName> > foundFiles;
const QVector<QmakeNodeStaticData::FileTypeData> &fileTypes = qmakeNodeStaticData()->fileTypeData;
// update files
QFileInfo tmpFi;
for (int i = 0; i < fileTypes.size(); ++i) {
@@ -663,7 +693,7 @@ void QmakePriFileNode::update(ProFile *includeFileExact, QtSupport::ProFileReade
QSet<Utils::FileName> newFilePaths;
foreach (const VariableAndVPathInformation &qmakeVariable, qmakeVariables) {
if (includeFileExact) {
QStringList tmp = readerExact->absoluteFileValues(qmakeVariable.variable, projectDir, qmakeVariable.vPathsExact, includeFileExact);
QStringList tmp = input.readerExact->absoluteFileValues(qmakeVariable.variable, input.projectDir, qmakeVariable.vPathsExact, includeFileExact);
foreach (const QString &t, tmp) {
tmpFi.setFile(t);
if (tmpFi.isFile())
@@ -671,7 +701,7 @@ void QmakePriFileNode::update(ProFile *includeFileExact, QtSupport::ProFileReade
}
}
if (includeFileCumlative) {
QStringList tmp = readerCumulative->absoluteFileValues(qmakeVariable.variable, projectDir, qmakeVariable.vPathsCumulative, includeFileCumlative);
QStringList tmp = input.readerCumulative->absoluteFileValues(qmakeVariable.variable, input.projectDir, qmakeVariable.vPathsCumulative, includeFileCumlative);
foreach (const QString &t, tmp) {
tmpFi.setFile(t);
if (tmpFi.isFile())
@@ -680,19 +710,39 @@ void QmakePriFileNode::update(ProFile *includeFileExact, QtSupport::ProFileReade
}
}
foundFiles[type] = newFilePaths;
m_recursiveEnumerateFiles.subtract(newFilePaths);
result.foundFiles[type] = newFilePaths;
result.recursiveEnumerateFiles.subtract(newFilePaths);
}
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
QSet<Utils::FileName> newFilePaths = filterFilesProVariables(type, foundFiles[type]);
newFilePaths += filterFilesRecursiveEnumerata(type, m_recursiveEnumerateFiles);
QSet<Utils::FileName> newFilePaths = filterFilesProVariables(type, result.foundFiles[type]);
newFilePaths += filterFilesRecursiveEnumerata(type, result.recursiveEnumerateFiles);
result.foundFiles[type] = newFilePaths;
}
return result;
}
void QmakePriFileNode::update(const Internal::PriFileEvalResult &result)
{
// add project file node
if (m_fileNodes.isEmpty())
addFileNodes(QList<FileNode *>() << new ProjectExplorer::FileNode(m_projectFilePath, ProjectExplorer::ProjectFileType, false));
m_recursiveEnumerateFiles = result.recursiveEnumerateFiles;
watchFolders(result.folders.toSet());
InternalNode contents;
const QVector<QmakeNodeStaticData::FileTypeData> &fileTypes = qmakeNodeStaticData()->fileTypeData;
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
const QSet<Utils::FileName> &newFilePaths = result.foundFiles.value(type);
// We only need to save this information if
// we are watching folders
if (!folders.isEmpty())
if (!result.folders.isEmpty())
m_files[type] = newFilePaths;
else
m_files[type].clear();
@@ -1355,13 +1405,13 @@ QStringList QmakePriFileNode::varNamesForRemoving()
}
QStringList QmakePriFileNode::dynamicVarNames(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative,
QtSupport::BaseQtVersion *qtVersion)
bool isQt5)
{
QStringList result;
// Figure out DEPLOYMENT and INSTALLS
const QString deployment = QLatin1String("DEPLOYMENT");
const QString sources = QLatin1String(qtVersion && qtVersion->qtVersion() < QtSupport::QtVersionNumber(5,0,0) ? ".sources" : ".files");
const QString sources = QLatin1String(isQt5 ? ".files" : ".sources");
QStringList listOfVars = readerExact->values(deployment);
foreach (const QString &var, listOfVars) {
result << (var + sources);
@@ -1681,15 +1731,33 @@ void QmakeProFileNode::asyncUpdate()
m_project->incrementPendingEvaluateFutures();
setupReader();
m_parseFutureWatcher.waitForFinished();
QFuture<EvalResult> future = QtConcurrent::run(&QmakeProFileNode::asyncEvaluate, this);
EvalInput input = evalInput();
QFuture<EvalResult *> future = QtConcurrent::run(&QmakeProFileNode::asyncEvaluate, this, input);
m_parseFutureWatcher.setFuture(future);
}
EvalInput QmakeProFileNode::evalInput() const
{
EvalInput input;
input.projectDir = m_projectDir;
input.projectFilePath = m_projectFilePath;
input.buildDirectory = buildDir();
input.readerExact = m_readerExact;
input.readerCumulative = m_readerCumulative;
ProjectExplorer::Target *t = m_project->activeTarget();
ProjectExplorer::Kit *k = t ? t->kit() : ProjectExplorer::KitManager::defaultKit();
QtSupport::BaseQtVersion *qtVersion = QtSupport::QtKitInformation::qtVersion(k);
input.isQt5 = !qtVersion || qtVersion->qtVersion() >= QtSupport::QtVersionNumber(5,0,0);
input.qmakeGlobals = m_project->qmakeGlobals();
input.qmakeVfs = m_project->qmakeVfs();
return input;
}
void QmakeProFileNode::update()
{
setParseInProgressRecursive(true);
setupReader();
EvalResult evalResult = evaluate();
EvalResult *evalResult = evaluate(evalInput());
applyEvaluate(evalResult, false);
}
@@ -1704,20 +1772,237 @@ void QmakeProFileNode::setupReader()
m_readerCumulative->setCumulative(true);
}
QmakeProFileNode::EvalResult QmakeProFileNode::evaluate()
static QStringList mergeList(const QStringList &listA, const QStringList &listB)
{
if (ProFile *pro = m_readerExact->parsedProFile(m_projectFilePath)) {
bool exactOk = m_readerExact->accept(pro, QMakeEvaluator::LoadAll);
bool cumulOk = m_readerCumulative->accept(pro, QMakeEvaluator::LoadPreFiles);
pro->deref();
return exactOk ? EvalOk : cumulOk ? EvalPartial : EvalFail;
QStringList result;
result.reserve(qMax(listA.size(), listB.size()));
auto ait = listA.constBegin();
auto aend = listA.constEnd();
auto bit = listB.constBegin();
auto bend = listB.constBegin();
while (ait != aend && bit != bend) {
const QString &a = *ait;
const QString &b = *bit;
if (a < b) {
result.append(a);
++ait;
} else if (b < a) {
result.append(b);
++bit;
} else {
result.append(a);
++ait;
++bit;
}
return EvalFail;
}
while (ait != aend) {
result.append(*ait);
++ait;
}
while (bit != bend) {
result.append(*bit);
++bit;
}
return result;
}
void QmakeProFileNode::asyncEvaluate(QFutureInterface<EvalResult> &fi)
EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
{
EvalResult evalResult = evaluate();
EvalResult *result = new EvalResult;
if (ProFile *pro = input.readerExact->parsedProFile(input.projectFilePath)) {
bool exactOk = input.readerExact->accept(pro, QMakeEvaluator::LoadAll);
bool cumulOk = input.readerCumulative->accept(pro, QMakeEvaluator::LoadPreFiles);
pro->deref();
result->state = exactOk ? EvalResult::EvalOk : cumulOk ? EvalResult::EvalPartial : EvalResult::EvalFail;
} else {
result->state = EvalResult::EvalFail;
}
if (result->state == EvalResult::EvalFail)
return result;
result->projectType = proFileTemplateTypeToProjectType(
(result->state == EvalResult::EvalOk ? input.readerExact
: input.readerCumulative)->templateType());
result->fileForCurrentProjectExact = 0;
result->fileForCurrentProjectCumlative = 0;
if (result->state == EvalResult::EvalOk) {
if (result->projectType == SubDirsTemplate) {
QStringList errors;
result->newProjectFilesExact = subDirsPaths(input.readerExact, input.projectDir, &result->subProjectsNotToDeploy, &errors);
result->errors.append(errors);
result->exactSubdirs = result->newProjectFilesExact.toSet();
}
foreach (ProFile *includeFile, input.readerExact->includeFiles()) {
if (includeFile->fileName() == input.projectFilePath) { // this file
result->fileForCurrentProjectExact = includeFile;
} else {
result->newProjectFilesExact << includeFile->fileName();
result->includeFilesExact.insert(includeFile->fileName(), includeFile);
}
}
}
if (result->projectType == SubDirsTemplate)
result->newProjectFilesCumlative = subDirsPaths(input.readerCumulative, input.projectDir, 0, 0);
foreach (ProFile *includeFile, input.readerCumulative->includeFiles()) {
if (includeFile->fileName() == input.projectFilePath) {
result->fileForCurrentProjectCumlative = includeFile;
} else {
result->newProjectFilesCumlative << includeFile->fileName();
result->includeFilesCumlative.insert(includeFile->fileName(), includeFile);
}
}
SortByPath sortByPath;
Utils::sort(result->newProjectFilesExact, sortByPath);
Utils::sort(result->newProjectFilesCumlative, sortByPath);
if (result->state == EvalResult::EvalOk) {
// create build_pass reader
QtSupport::ProFileReader *readerBuildPass = 0;
QStringList builds = input.readerExact->values(QLatin1String("BUILDS"));
if (builds.isEmpty()) {
readerBuildPass = input.readerExact;
} else {
QString build = builds.first();
QHash<QString, QStringList> basevars;
QStringList basecfgs = input.readerExact->values(build + QLatin1String(".CONFIG"));
basecfgs += build;
basecfgs += QLatin1String("build_pass");
basevars[QLatin1String("BUILD_PASS")] = QStringList(build);
QStringList buildname = input.readerExact->values(build + QLatin1String(".name"));
basevars[QLatin1String("BUILD_NAME")] = (buildname.isEmpty() ? QStringList(build) : buildname);
// We don't increase/decrease m_qmakeGlobalsRefCnt here, because the outer profilereaders keep m_qmakeGlobals alive anyway
readerBuildPass = new QtSupport::ProFileReader(input.qmakeGlobals, input.qmakeVfs); // needs to access m_qmakeGlobals, m_qmakeVfs
readerBuildPass->setOutputDir(input.buildDirectory);
readerBuildPass->setExtraVars(basevars);
readerBuildPass->setExtraConfigs(basecfgs);
EvalResult::EvalResultState evalResultBuildPass = EvalResult::EvalOk;
if (ProFile *pro = readerBuildPass->parsedProFile(input.projectFilePath)) {
if (!readerBuildPass->accept(pro, QMakeEvaluator::LoadAll))
evalResultBuildPass = EvalResult::EvalPartial;
pro->deref();
} else {
evalResultBuildPass = EvalResult::EvalFail;
}
if (evalResultBuildPass != EvalResult::EvalOk) {
delete readerBuildPass;
readerBuildPass = 0;
}
}
result->targetInformation = targetInformation(input.readerExact, readerBuildPass, input.buildDirectory, input.projectFilePath);
result->resolvedMkspecPath = input.readerExact->resolvedMkSpec();
result->installsList = installsList(readerBuildPass, input.projectFilePath, input.projectDir);
// update other variables
result->newVarValues[DefinesVar] = input.readerExact->values(QLatin1String("DEFINES"));
result->newVarValues[IncludePathVar] = includePaths(input.readerExact, input.buildDirectory, input.projectDir);
result->newVarValues[CppFlagsVar] = input.readerExact->values(QLatin1String("QMAKE_CXXFLAGS"));
result->newVarValues[CppHeaderVar] = fileListForVar(input.readerExact, input.readerCumulative,
QLatin1String("HEADERS"), input.projectDir, input.buildDirectory);
result->newVarValues[CppSourceVar] = fileListForVar(input.readerExact, input.readerCumulative,
QLatin1String("SOURCES"), input.projectDir, input.buildDirectory);
result->newVarValues[ObjCSourceVar] = fileListForVar(input.readerExact, input.readerCumulative,
QLatin1String("OBJECTIVE_SOURCES"), input.projectDir, input.buildDirectory);
result->newVarValues[ObjCHeaderVar] = fileListForVar(input.readerExact, input.readerCumulative,
QLatin1String("OBJECTIVE_HEADERS"), input.projectDir, input.buildDirectory);
result->newVarValues[UiDirVar] = QStringList() << uiDirPath(input.readerExact, input.buildDirectory);
result->newVarValues[MocDirVar] = QStringList() << mocDirPath(input.readerExact, input.buildDirectory);
result->newVarValues[ResourceVar] = fileListForVar(input.readerExact, input.readerCumulative,
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
result->newVarValues[ExactResourceVar] = fileListForVar(input.readerExact, 0,
QLatin1String("RESOURCES"), input.projectDir, input.buildDirectory);
result->newVarValues[PkgConfigVar] = input.readerExact->values(QLatin1String("PKGCONFIG"));
result->newVarValues[PrecompiledHeaderVar] =
input.readerExact->absoluteFileValues(QLatin1String("PRECOMPILED_HEADER"),
input.projectDir,
QStringList() << input.projectDir,
0);
result->newVarValues[LibDirectoriesVar] = libDirectories(input.readerExact);
result->newVarValues[ConfigVar] = input.readerExact->values(QLatin1String("CONFIG"));
result->newVarValues[QmlImportPathVar] = input.readerExact->absolutePathValues(
QLatin1String("QML_IMPORT_PATH"), input.projectDir);
result->newVarValues[Makefile] = input.readerExact->values(QLatin1String("MAKEFILE"));
result->newVarValues[QtVar] = input.readerExact->values(QLatin1String("QT"));
result->newVarValues[ObjectExt] = input.readerExact->values(QLatin1String("QMAKE_EXT_OBJ"));
result->newVarValues[ObjectsDir] = input.readerExact->values(QLatin1String("OBJECTS_DIR"));
result->newVarValues[VersionVar] = input.readerExact->values(QLatin1String("VERSION"));
result->newVarValues[TargetExtVar] = input.readerExact->values(QLatin1String("TARGET_EXT"));
result->newVarValues[TargetVersionExtVar]
= input.readerExact->values(QLatin1String("TARGET_VERSION_EXT"));
result->newVarValues[StaticLibExtensionVar] = input.readerExact->values(QLatin1String("QMAKE_EXTENSION_STATICLIB"));
result->newVarValues[ShLibExtensionVar] = input.readerExact->values(QLatin1String("QMAKE_EXTENSION_SHLIB"));
result->newVarValues[AndroidArchVar] = input.readerExact->values(QLatin1String("ANDROID_TARGET_ARCH"));
result->newVarValues[AndroidDeploySettingsFile] = input.readerExact->values(QLatin1String("ANDROID_DEPLOYMENT_SETTINGS_FILE"));
result->newVarValues[AndroidPackageSourceDir] = input.readerExact->values(QLatin1String("ANDROID_PACKAGE_SOURCE_DIR"));
result->newVarValues[AndroidExtraLibs] = input.readerExact->values(QLatin1String("ANDROID_EXTRA_LIBS"));
result->isDeployable = false;
if (result->projectType == ApplicationTemplate) {
result->isDeployable = true;
} else {
foreach (const QString &item, input.readerExact->values(QLatin1String("DEPLOYMENT"))) {
if (!input.readerExact->values(item + QLatin1String(".sources")).isEmpty()) {
result->isDeployable = true;
break;
}
}
}
if (readerBuildPass && readerBuildPass != input.readerExact)
delete readerBuildPass;
QList<QList<VariableAndVPathInformation>> variableAndVPathInformation;
{ // Collect information on VPATHS and qmake variables
QStringList baseVPathsExact = baseVPaths(input.readerExact, input.projectDir, input.buildDirectory);
QStringList baseVPathsCumulative = baseVPaths(input.readerCumulative, input.projectDir, input.buildDirectory);
const QVector<QmakeNodeStaticData::FileTypeData> &fileTypes = qmakeNodeStaticData()->fileTypeData;
variableAndVPathInformation.reserve(fileTypes.size());
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
QList<VariableAndVPathInformation> list;
QStringList qmakeVariables = varNames(type, input.readerExact);
list.reserve(qmakeVariables.size());
foreach (const QString &qmakeVariable, qmakeVariables) {
VariableAndVPathInformation info;
info.variable = qmakeVariable;
info.vPathsExact = fullVPaths(baseVPathsExact, input.readerExact, qmakeVariable, input.projectDir);
info.vPathsCumulative = fullVPaths(baseVPathsCumulative, input.readerCumulative, qmakeVariable, input.projectDir);
list.append(info);
}
variableAndVPathInformation.append(list);
}
}
// extract values
QStringList allFiles = mergeList(result->newProjectFilesExact, result->newProjectFilesCumlative);
foreach (const QString &file, allFiles) {
ProFile *fileExact = result->includeFilesExact.value(file);
ProFile *fileCumlative = result->includeFilesCumlative.value(file);
if (fileExact || fileCumlative) {
result->priFileResults[file] = extractValues(input, fileExact, fileCumlative, variableAndVPathInformation);
}
}
result->priFileResults[input.projectFilePath] = extractValues(input, result->fileForCurrentProjectExact,
result->fileForCurrentProjectCumlative,
variableAndVPathInformation);
}
return result;
}
void QmakeProFileNode::asyncEvaluate(QFutureInterface<EvalResult *> &fi, EvalInput input)
{
EvalResult *evalResult = evaluate(input);
fi.reportResult(evalResult);
}
@@ -1732,11 +2017,17 @@ bool sortByNodes(Node *a, Node *b)
return a->path() < b->path();
}
void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
void QmakeProFileNode::applyEvaluate(EvalResult *evalResult, bool async)
{
QScopedPointer<EvalResult> result(evalResult);
if (!m_readerExact)
return;
if (evalResult == EvalFail || m_project->wasEvaluateCanceled()) {
foreach (const QString &error, evalResult->errors)
QmakeProject::proFileParseError(error);
// we are changing what is executed in that case
if (result->state == EvalResult::EvalFail || m_project->wasEvaluateCanceled()) {
m_validParse = false;
m_project->destroyProFileReader(m_readerExact);
m_project->destroyProFileReader(m_readerCumulative);
@@ -1744,7 +2035,7 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
setValidParseRecursive(false);
setParseInProgressRecursive(false);
if (evalResult == EvalFail) {
if (result->state == EvalResult::EvalFail) {
QmakeProject::proFileParseError(tr("Error while parsing file %1. Giving up.").arg(m_projectFilePath));
if (m_projectType == InvalidProject)
return;
@@ -1768,9 +2059,7 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
if (debug)
qDebug() << "QmakeProFileNode - updating files for file " << m_projectFilePath;
QmakeProjectType projectType = proFileTemplateTypeToProjectType(
(evalResult == EvalOk ? m_readerExact : m_readerCumulative)->templateType());
if (projectType != m_projectType) {
if (result->projectType != m_projectType) {
QmakeProjectType oldType = m_projectType;
// probably all subfiles/projects have changed anyway
// delete files && folders && projects
@@ -1785,12 +2074,12 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
removeProjectNodes(subProjectNodes());
removeFolderNodes(subFolderNodes());
bool changesShowInSimpleTree = showInSimpleTree() ^ showInSimpleTree(projectType);
bool changesShowInSimpleTree = showInSimpleTree() ^ showInSimpleTree(result->projectType);
if (changesShowInSimpleTree)
aboutToChangeShowInSimpleTree();
m_projectType = projectType;
m_projectType = result->projectType;
if (changesShowInSimpleTree)
showInSimpleTreeChanged();
@@ -1799,7 +2088,7 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
// so we kind of can ignore that question for now
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
if (Internal::QmakeNodesWatcher *qmakeWatcher = qobject_cast<Internal::QmakeNodesWatcher*>(watcher))
emit qmakeWatcher->projectTypeChanged(this, oldType, projectType);
emit qmakeWatcher->projectTypeChanged(this, oldType, result->projectType);
}
//
@@ -1808,82 +2097,22 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
QList<ProjectNode*> existingProjectNodes = subProjectNodes();
QStringList newProjectFilesExact;
QHash<QString, ProFile*> includeFilesExact;
QSet<QString> exactSubdirs;
ProFile *fileForCurrentProjectExact = 0;
QStringList subProjectsNotToDeploy;
if (evalResult == EvalOk) {
if (m_projectType == SubDirsTemplate) {
newProjectFilesExact = subDirsPaths(m_readerExact, &subProjectsNotToDeploy, false);
exactSubdirs = newProjectFilesExact.toSet();
}
foreach (ProFile *includeFile, m_readerExact->includeFiles()) {
if (includeFile->fileName() == m_projectFilePath) { // this file
fileForCurrentProjectExact = includeFile;
} else {
newProjectFilesExact << includeFile->fileName();
includeFilesExact.insert(includeFile->fileName(), includeFile);
}
}
}
QStringList newProjectFilesCumlative;
QHash<QString, ProFile*> includeFilesCumlative;
ProFile *fileForCurrentProjectCumlative = 0;
if (m_projectType == SubDirsTemplate)
newProjectFilesCumlative = subDirsPaths(m_readerCumulative, 0, true);
foreach (ProFile *includeFile, m_readerCumulative->includeFiles()) {
if (includeFile->fileName() == m_projectFilePath) {
fileForCurrentProjectCumlative = includeFile;
} else {
newProjectFilesCumlative << includeFile->fileName();
includeFilesCumlative.insert(includeFile->fileName(), includeFile);
}
}
QString buildDirectory = buildDir();
QList<QList<VariableAndVPathInformation>> variableAndVPathInformation;
{ // Collect information on VPATHS and qmake variables
QStringList baseVPathsExact = baseVPaths(m_readerExact, m_projectDir, buildDirectory);
QStringList baseVPathsCumulative = baseVPaths(m_readerCumulative, m_projectDir, buildDirectory);
const QVector<QmakeNodeStaticData::FileTypeData> &fileTypes = qmakeNodeStaticData()->fileTypeData;
variableAndVPathInformation.reserve(fileTypes.size());
for (int i = 0; i < fileTypes.size(); ++i) {
FileType type = fileTypes.at(i).type;
QList<VariableAndVPathInformation> list;
QStringList qmakeVariables = varNames(type, m_readerExact);
list.reserve(qmakeVariables.size());
foreach (const QString &qmakeVariable, qmakeVariables) {
VariableAndVPathInformation info;
info.variable = qmakeVariable;
info.vPathsExact = fullVPaths(baseVPathsExact, m_readerExact, qmakeVariable, m_projectDir);
info.vPathsCumulative = fullVPaths(baseVPathsCumulative, m_readerCumulative, qmakeVariable, m_projectDir);
list.append(info);
}
variableAndVPathInformation.append(list);
}
}
SortByPath sortByPath;
Utils::sort(existingProjectNodes, sortByPath);
Utils::sort(newProjectFilesExact, sortByPath);
Utils::sort(newProjectFilesCumlative, sortByPath);
// result is already sorted
QList<ProjectNode*> toAdd;
QList<ProjectNode*> toRemove;
QList<ProjectNode*>::const_iterator existingIt = existingProjectNodes.constBegin();
QStringList::const_iterator newExactIt = newProjectFilesExact.constBegin();
QStringList::const_iterator newCumlativeIt = newProjectFilesCumlative.constBegin();
QStringList::const_iterator newExactIt = result->newProjectFilesExact.constBegin();
QStringList::const_iterator newCumlativeIt = result->newProjectFilesCumlative.constBegin();
forever {
bool existingAtEnd = (existingIt == existingProjectNodes.constEnd());
bool newExactAtEnd = (newExactIt == newProjectFilesExact.constEnd());
bool newCumlativeAtEnd = (newCumlativeIt == newProjectFilesCumlative.constEnd());
bool newExactAtEnd = (newExactIt == result->newProjectFilesExact.constEnd());
bool newCumlativeAtEnd = (newCumlativeIt == result->newProjectFilesCumlative.constEnd());
if (existingAtEnd && newExactAtEnd && newCumlativeAtEnd)
break; // we are done, hurray!
@@ -1937,19 +2166,18 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
++newCumlativeIt;
}
// Update existingNodeIte
ProFile *fileExact = includeFilesExact.value((*existingIt)->path());
ProFile *fileCumlative = includeFilesCumlative.value((*existingIt)->path());
ProFile *fileExact = result->includeFilesExact.value((*existingIt)->path());
ProFile *fileCumlative = result->includeFilesCumlative.value((*existingIt)->path());
if (fileExact || fileCumlative) {
QmakePriFileNode *priFileNode = static_cast<QmakePriFileNode *>(*existingIt);
priFileNode->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative,
buildDirectory, variableAndVPathInformation);
priFileNode->update(result->priFileResults[(*existingIt)->path()]);
priFileNode->setIncludedInExactParse(fileExact != 0 && includedInExactParse());
} else {
// We always parse exactly, because we later when async parsing don't know whether
// the .pro file is included in this .pro file
// So to compare that later parse with the sync one
QmakeProFileNode *proFileNode = static_cast<QmakeProFileNode *>(*existingIt);
proFileNode->setIncludedInExactParse(exactSubdirs.contains(proFileNode->path()) && includedInExactParse());
proFileNode->setIncludedInExactParse(result->exactSubdirs.contains(proFileNode->path()) && includedInExactParse());
if (async)
proFileNode->asyncUpdate();
else
@@ -1961,8 +2189,8 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
}
// If we found something to add, do it
if (!nodeToAdd.isEmpty()) {
ProFile *fileExact = includeFilesExact.value(nodeToAdd);
ProFile *fileCumlative = includeFilesCumlative.value(nodeToAdd);
ProFile *fileExact = result->includeFilesExact.value(nodeToAdd);
ProFile *fileCumlative = result->includeFilesCumlative.value(nodeToAdd);
// Loop preventation, make sure that exact same node is not in our parent chain
bool loop = false;
@@ -1980,13 +2208,12 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
QmakePriFileNode *qmakePriFileNode = new QmakePriFileNode(m_project, this, nodeToAdd);
qmakePriFileNode->setParentFolderNode(this); // Needed for loop detection
qmakePriFileNode->setIncludedInExactParse(fileExact != 0 && includedInExactParse());
qmakePriFileNode->update(fileExact, m_readerExact, fileCumlative, m_readerCumulative,
buildDirectory, variableAndVPathInformation);
qmakePriFileNode->update(result->priFileResults[nodeToAdd]);
toAdd << qmakePriFileNode;
} else {
QmakeProFileNode *qmakeProFileNode = new QmakeProFileNode(m_project, nodeToAdd);
qmakeProFileNode->setParentFolderNode(this); // Needed for loop detection
qmakeProFileNode->setIncludedInExactParse(exactSubdirs.contains(qmakeProFileNode->path()) && includedInExactParse());
qmakeProFileNode->setIncludedInExactParse(result->exactSubdirs.contains(qmakeProFileNode->path()) && includedInExactParse());
if (async)
qmakeProFileNode->asyncUpdate();
else
@@ -2008,121 +2235,27 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
if (!toAdd.isEmpty())
addProjectNodes(toAdd);
QmakePriFileNode::update(fileForCurrentProjectExact, m_readerExact, fileForCurrentProjectCumlative, m_readerCumulative,
buildDirectory, variableAndVPathInformation);
QmakePriFileNode::update(result->priFileResults[m_projectFilePath]);
m_validParse = (evalResult == EvalOk);
m_validParse = (result->state == EvalResult::EvalOk);
if (m_validParse) {
// create build_pass reader
QtSupport::ProFileReader *readerBuildPass = 0;
QStringList builds = m_readerExact->values(QLatin1String("BUILDS"));
if (builds.isEmpty()) {
readerBuildPass = m_readerExact;
} else {
QString build = builds.first();
QHash<QString, QStringList> basevars;
QStringList basecfgs = m_readerExact->values(build + QLatin1String(".CONFIG"));
basecfgs += build;
basecfgs += QLatin1String("build_pass");
basevars[QLatin1String("BUILD_PASS")] = QStringList(build);
QStringList buildname = m_readerExact->values(build + QLatin1String(".name"));
basevars[QLatin1String("BUILD_NAME")] = (buildname.isEmpty() ? QStringList(build) : buildname);
readerBuildPass = m_project->createProFileReader(this);
readerBuildPass->setExtraVars(basevars);
readerBuildPass->setExtraConfigs(basecfgs);
EvalResult evalResult = EvalOk;
if (ProFile *pro = readerBuildPass->parsedProFile(m_projectFilePath)) {
if (!readerBuildPass->accept(pro, QMakeEvaluator::LoadAll))
evalResult = EvalPartial;
pro->deref();
} else {
evalResult = EvalFail;
}
if (evalResult != EvalOk) {
m_project->destroyProFileReader(readerBuildPass);
readerBuildPass = 0;
}
}
// update TargetInformation
m_qmakeTargetInformation = targetInformation(m_readerExact, readerBuildPass, buildDirectory);
m_resolvedMkspecPath = m_readerExact->resolvedMkSpec();
m_qmakeTargetInformation = result->targetInformation;
m_resolvedMkspecPath = result->resolvedMkspecPath;
m_subProjectsNotToDeploy = subProjectsNotToDeploy;
setupInstallsList(readerBuildPass);
m_subProjectsNotToDeploy = result->subProjectsNotToDeploy;
m_installsList = result->installsList;
m_isDeployable = result->isDeployable;
// update other variables
QHash<QmakeVariable, QStringList> newVarValues;
newVarValues[DefinesVar] = m_readerExact->values(QLatin1String("DEFINES"));
newVarValues[IncludePathVar] = includePaths(m_readerExact, buildDirectory);
newVarValues[CppFlagsVar] = m_readerExact->values(QLatin1String("QMAKE_CXXFLAGS"));
newVarValues[CppHeaderVar] = fileListForVar(m_readerExact, m_readerCumulative,
QLatin1String("HEADERS"), m_projectDir, buildDirectory);
newVarValues[CppSourceVar] = fileListForVar(m_readerExact, m_readerCumulative,
QLatin1String("SOURCES"), m_projectDir, buildDirectory);
newVarValues[ObjCSourceVar] = fileListForVar(m_readerExact, m_readerCumulative,
QLatin1String("OBJECTIVE_SOURCES"), m_projectDir, buildDirectory);
newVarValues[ObjCHeaderVar] = fileListForVar(m_readerExact, m_readerCumulative,
QLatin1String("OBJECTIVE_HEADERS"), m_projectDir, buildDirectory);
newVarValues[UiDirVar] = QStringList() << uiDirPath(m_readerExact, buildDirectory);
newVarValues[MocDirVar] = QStringList() << mocDirPath(m_readerExact, buildDirectory);
newVarValues[ResourceVar] = fileListForVar(m_readerExact, m_readerCumulative,
QLatin1String("RESOURCES"), m_projectDir, buildDirectory);
newVarValues[ExactResourceVar] = fileListForVar(m_readerExact, 0,
QLatin1String("RESOURCES"), m_projectDir, buildDirectory);
newVarValues[PkgConfigVar] = m_readerExact->values(QLatin1String("PKGCONFIG"));
newVarValues[PrecompiledHeaderVar] =
m_readerExact->absoluteFileValues(QLatin1String("PRECOMPILED_HEADER"),
m_projectDir,
QStringList() << m_projectDir,
0);
newVarValues[LibDirectoriesVar] = libDirectories(m_readerExact);
newVarValues[ConfigVar] = m_readerExact->values(QLatin1String("CONFIG"));
newVarValues[QmlImportPathVar] = m_readerExact->absolutePathValues(
QLatin1String("QML_IMPORT_PATH"), m_projectDir);
newVarValues[Makefile] = m_readerExact->values(QLatin1String("MAKEFILE"));
newVarValues[QtVar] = m_readerExact->values(QLatin1String("QT"));
newVarValues[ObjectExt] = m_readerExact->values(QLatin1String("QMAKE_EXT_OBJ"));
newVarValues[ObjectsDir] = m_readerExact->values(QLatin1String("OBJECTS_DIR"));
newVarValues[VersionVar] = m_readerExact->values(QLatin1String("VERSION"));
newVarValues[TargetExtVar] = m_readerExact->values(QLatin1String("TARGET_EXT"));
newVarValues[TargetVersionExtVar]
= m_readerExact->values(QLatin1String("TARGET_VERSION_EXT"));
newVarValues[StaticLibExtensionVar] = m_readerExact->values(QLatin1String("QMAKE_EXTENSION_STATICLIB"));
newVarValues[ShLibExtensionVar] = m_readerExact->values(QLatin1String("QMAKE_EXTENSION_SHLIB"));
newVarValues[AndroidArchVar] = m_readerExact->values(QLatin1String("ANDROID_TARGET_ARCH"));
newVarValues[AndroidDeploySettingsFile] = m_readerExact->values(QLatin1String("ANDROID_DEPLOYMENT_SETTINGS_FILE"));
newVarValues[AndroidPackageSourceDir] = m_readerExact->values(QLatin1String("ANDROID_PACKAGE_SOURCE_DIR"));
newVarValues[AndroidExtraLibs] = m_readerExact->values(QLatin1String("ANDROID_EXTRA_LIBS"));
m_isDeployable = false;
if (m_projectType == ApplicationTemplate) {
m_isDeployable = true;
} else {
foreach (const QString &item, m_readerExact->values(QLatin1String("DEPLOYMENT"))) {
if (!m_readerExact->values(item + QLatin1String(".sources")).isEmpty()) {
m_isDeployable = true;
break;
}
}
}
if (readerBuildPass && readerBuildPass != m_readerExact)
m_project->destroyProFileReader(readerBuildPass);
if (m_varValues != newVarValues) {
if (m_varValues != result->newVarValues) {
QmakeVariablesHash oldValues = m_varValues;
m_varValues = newVarValues;
m_varValues = result->newVarValues;
foreach (ProjectExplorer::NodesWatcher *watcher, watchers())
if (Internal::QmakeNodesWatcher *qmakeWatcher = qobject_cast<Internal::QmakeNodesWatcher*>(watcher))
emit qmakeWatcher->variablesChanged(this, oldValues, m_varValues);
}
} // evalResult == EvalOk
} // result == EvalOk
setParseInProgress(false);
@@ -2136,7 +2269,7 @@ void QmakeProFileNode::applyEvaluate(EvalResult evalResult, bool async)
}
QStringList QmakeProFileNode::fileListForVar(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative,
const QString &varName, const QString &projectDir, const QString &buildDir) const
const QString &varName, const QString &projectDir, const QString &buildDir)
{
QStringList baseVPathsExact = baseVPaths(readerExact, projectDir, buildDir);
QStringList vPathsExact = fullVPaths(baseVPathsExact, readerExact, varName, projectDir);
@@ -2158,7 +2291,7 @@ QStringList QmakeProFileNode::fileListForVar(QtSupport::ProFileReader *readerExa
return result;
}
QString QmakeProFileNode::uiDirPath(QtSupport::ProFileReader *reader, const QString &buildDir) const
QString QmakeProFileNode::uiDirPath(QtSupport::ProFileReader *reader, const QString &buildDir)
{
QString path = reader->value(QLatin1String("UI_DIR"));
if (QFileInfo(path).isRelative())
@@ -2166,7 +2299,7 @@ QString QmakeProFileNode::uiDirPath(QtSupport::ProFileReader *reader, const QStr
return path;
}
QString QmakeProFileNode::mocDirPath(QtSupport::ProFileReader *reader, const QString &buildDir) const
QString QmakeProFileNode::mocDirPath(QtSupport::ProFileReader *reader, const QString &buildDir)
{
QString path = reader->value(QLatin1String("MOC_DIR"));
if (QFileInfo(path).isRelative())
@@ -2174,27 +2307,27 @@ QString QmakeProFileNode::mocDirPath(QtSupport::ProFileReader *reader, const QSt
return path;
}
QStringList QmakeProFileNode::includePaths(QtSupport::ProFileReader *reader, const QString &buildDir) const
QStringList QmakeProFileNode::includePaths(QtSupport::ProFileReader *reader, const QString &buildDir, const QString &projectDir)
{
QStringList paths;
foreach (const QString &cxxflags, m_readerExact->values(QLatin1String("QMAKE_CXXFLAGS"))) {
foreach (const QString &cxxflags, reader->values(QLatin1String("QMAKE_CXXFLAGS"))) {
if (cxxflags.startsWith(QLatin1String("-I")))
paths.append(cxxflags.mid(2));
}
paths.append(reader->absolutePathValues(QLatin1String("INCLUDEPATH"), m_projectDir));
paths.append(reader->absolutePathValues(QLatin1String("QMAKE_INCDIR"), m_projectDir));
paths.append(reader->absolutePathValues(QLatin1String("INCLUDEPATH"), projectDir));
paths.append(reader->absolutePathValues(QLatin1String("QMAKE_INCDIR"), projectDir));
// paths already contains moc dir and ui dir, due to corrrectly parsing uic.prf and moc.prf
// except if those directories don't exist at the time of parsing
// thus we add those directories manually (without checking for existence)
paths << mocDirPath(reader, buildDir) << uiDirPath(reader, buildDir);
// qmake always adds "."
paths << m_projectDir;
paths << projectDir;
paths.removeDuplicates();
return paths;
}
QStringList QmakeProFileNode::libDirectories(QtSupport::ProFileReader *reader) const
QStringList QmakeProFileNode::libDirectories(QtSupport::ProFileReader *reader)
{
QStringList result;
foreach (const QString &str, reader->values(QLatin1String("LIBS"))) {
@@ -2204,8 +2337,10 @@ QStringList QmakeProFileNode::libDirectories(QtSupport::ProFileReader *reader) c
return result;
}
QStringList QmakeProFileNode::subDirsPaths(QtSupport::ProFileReader *reader, QStringList *subProjectsNotToDeploy,
bool silent) const
QStringList QmakeProFileNode::subDirsPaths(QtSupport::ProFileReader *reader,
const QString &projectDir,
QStringList *subProjectsNotToDeploy,
QStringList *errors)
{
QStringList subProjectPaths;
@@ -2230,7 +2365,7 @@ QStringList QmakeProFileNode::subDirsPaths(QtSupport::ProFileReader *reader, QSt
realDir = subDirVar;
QFileInfo info(realDir);
if (!info.isAbsolute())
info.setFile(m_projectDir + QLatin1Char('/') + realDir);
info.setFile(projectDir + QLatin1Char('/') + realDir);
realDir = info.filePath();
QString realFile;
@@ -2248,8 +2383,8 @@ QStringList QmakeProFileNode::subDirsPaths(QtSupport::ProFileReader *reader, QSt
subProjectsNotToDeploy->append(realFile);
}
} else {
if (!silent)
QmakeProject::proFileParseError(tr("Could not find .pro file for sub dir \"%1\" in \"%2\"")
if (errors)
errors->append(tr("Could not find .pro file for sub dir \"%1\" in \"%2\"")
.arg(subDirVar).arg(realDir));
}
}
@@ -2258,7 +2393,7 @@ QStringList QmakeProFileNode::subDirsPaths(QtSupport::ProFileReader *reader, QSt
return subProjectPaths;
}
TargetInformation QmakeProFileNode::targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir) const
TargetInformation QmakeProFileNode::targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir, const QString &projectFilePath)
{
TargetInformation result;
if (!reader || !readerBuildPass)
@@ -2279,7 +2414,7 @@ TargetInformation QmakeProFileNode::targetInformation(QtSupport::ProFileReader *
// Target
result.target = readerBuildPass->value(QLatin1String("TARGET"));
if (result.target.isEmpty())
result.target = QFileInfo(m_projectFilePath).baseName();
result.target = QFileInfo(projectFilePath).baseName();
result.valid = true;
@@ -2296,11 +2431,11 @@ QString QmakeProFileNode::resolvedMkspecPath() const
return m_resolvedMkspecPath;
}
void QmakeProFileNode::setupInstallsList(const QtSupport::ProFileReader *reader)
InstallsList QmakeProFileNode::installsList(const QtSupport::ProFileReader *reader, const QString &projectFilePath, const QString &projectDir)
{
m_installsList.clear();
InstallsList result;
if (!reader)
return;
return result;
const QStringList &itemList = reader->values(QLatin1String("INSTALLS"));
foreach (const QString &item, itemList) {
if (reader->values(item + QLatin1String(".CONFIG")).contains(QLatin1String("no_default_install")))
@@ -2313,7 +2448,7 @@ void QmakeProFileNode::setupInstallsList(const QtSupport::ProFileReader *reader)
qPrintable(pathVar), itemPaths.count());
if (itemPaths.isEmpty()) {
qDebug("%s: Ignoring INSTALLS item '%s', because it has no path.",
qPrintable(m_projectFilePath), qPrintable(item));
qPrintable(projectFilePath), qPrintable(item));
continue;
}
}
@@ -2321,9 +2456,9 @@ void QmakeProFileNode::setupInstallsList(const QtSupport::ProFileReader *reader)
const QStringList &itemFiles
= reader->absoluteFileValues(item + QLatin1String(".files"),
m_projectDir, QStringList() << m_projectDir, 0);
projectDir, QStringList() << projectDir, 0);
if (item == QLatin1String("target")) {
m_installsList.targetPath = itemPath;
result.targetPath = itemPath;
} else {
if (itemFiles.isEmpty()) {
// TODO: Fix QMAKE_SUBSTITUTES handling in pro file reader, then uncomment again
@@ -2334,9 +2469,10 @@ void QmakeProFileNode::setupInstallsList(const QtSupport::ProFileReader *reader)
// }
continue;
}
m_installsList.items << InstallsItem(itemPath, itemFiles);
result.items << InstallsItem(itemPath, itemFiles);
}
}
return result;
}
InstallsList QmakeProFileNode::installsList() const

View File

@@ -132,7 +132,10 @@ namespace Internal {
class QmakePriFile;
struct InternalNode;
class EvalInput;
class EvalResult;
class PriFileEvalResult;
// TOOD can probably move into the .cpp file
class VariableAndVPathInformation
{
public:
@@ -152,10 +155,7 @@ public:
QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmakeProFileNode, const QString &filePath);
~QmakePriFileNode();
void update(ProFile *includeFileExact, QtSupport::ProFileReader *readerExact,
ProFile *includeFileCumlative, QtSupport::ProFileReader *readerCumalative,
const QString &buildDir,
const QList<QList<Internal::VariableAndVPathInformation> > &variableAndVPathInformation);
void update(const Internal::PriFileEvalResult &result);
// ProjectNode interface
@@ -195,7 +195,7 @@ protected:
static QStringList varNames(ProjectExplorer::FileType type, QtSupport::ProFileReader *readerExact);
static QStringList varNamesForRemoving();
static QString varNameForAdding(const QString &mimeType);
static QStringList dynamicVarNames(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative, QtSupport::BaseQtVersion *qtVersion);
static QStringList dynamicVarNames(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative, bool isQt5);
static QSet<Utils::FileName> filterFilesProVariables(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
static QSet<Utils::FileName> filterFilesRecursiveEnumerata(ProjectExplorer::FileType fileType, const QSet<Utils::FileName> &files);
@@ -220,8 +220,10 @@ private:
bool priFileWritable(const QString &path);
bool saveModifiedEditors();
QStringList formResources(const QString &formFile) const;
QStringList baseVPaths(QtSupport::ProFileReader *reader, const QString &projectDir, const QString &buildDir) const;
QStringList fullVPaths(const QStringList &baseVPaths, QtSupport::ProFileReader *reader, const QString &qmakeVariable, const QString &projectDir) 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 *includeFileExact, ProFile *includeFileCumlative,
const QList<QList<Internal::VariableAndVPathInformation>> &variableAndVPathInformation);
void watchFolders(const QSet<QString> &folders);
QmakeProject *m_project;
@@ -437,26 +439,27 @@ private slots:
private:
void setupReader();
enum EvalResult { EvalAbort, EvalFail, EvalPartial, EvalOk };
EvalResult evaluate();
void applyEvaluate(EvalResult parseResult, bool async);
Internal::EvalInput evalInput() const;
void asyncEvaluate(QFutureInterface<EvalResult> &fi);
static Internal::EvalResult *evaluate(const Internal::EvalInput &input);
void applyEvaluate(Internal::EvalResult *parseResult, bool async);
void asyncEvaluate(QFutureInterface<Internal::EvalResult *> &fi, Internal::EvalInput input);
typedef QHash<QmakeVariable, QStringList> QmakeVariablesHash;
void updateUiFiles(const QString &buildDir);
QStringList fileListForVar(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative,
const QString &varName, const QString &projectDir, const QString &buildDir) const;
QString uiDirPath(QtSupport::ProFileReader *reader, const QString &buildDir) const;
QString mocDirPath(QtSupport::ProFileReader *reader, const QString &buildDir) const;
QStringList includePaths(QtSupport::ProFileReader *reader, const QString &buildDir) const;
QStringList libDirectories(QtSupport::ProFileReader *reader) const;
QStringList subDirsPaths(QtSupport::ProFileReader *reader, QStringList *subProjectsNotToDeploy, bool silent) const;
static QStringList fileListForVar(QtSupport::ProFileReader *readerExact, QtSupport::ProFileReader *readerCumulative,
const QString &varName, const QString &projectDir, const QString &buildDir);
static QString uiDirPath(QtSupport::ProFileReader *reader, const QString &buildDir);
static QString mocDirPath(QtSupport::ProFileReader *reader, const QString &buildDir);
static QStringList includePaths(QtSupport::ProFileReader *reader, const QString &buildDir, const QString &projectDir);
static QStringList libDirectories(QtSupport::ProFileReader *reader);
static QStringList subDirsPaths(QtSupport::ProFileReader *reader, const QString &projectDir, QStringList *subProjectsNotToDeploy, QStringList *errors);
TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir) const;
void setupInstallsList(const QtSupport::ProFileReader *reader);
static TargetInformation targetInformation(QtSupport::ProFileReader *reader, QtSupport::ProFileReader *readerBuildPass, const QString &buildDir, const QString &projectFilePath);
static InstallsList installsList(const QtSupport::ProFileReader *reader, const QString &projectFilePath, const QString &projectDir);
bool m_isDeployable;
@@ -475,7 +478,7 @@ private:
QHash<QString, QString> m_uiFiles; // ui-file path, ui header path
// Async stuff
QFutureWatcher<EvalResult> m_parseFutureWatcher;
QFutureWatcher<Internal::EvalResult *> m_parseFutureWatcher;
QtSupport::ProFileReader *m_readerExact;
QtSupport::ProFileReader *m_readerCumulative;
};

View File

@@ -1055,6 +1055,11 @@ ProFileGlobals *QmakeProject::qmakeGlobals()
return m_qmakeGlobals;
}
QMakeVfs *QmakeProject::qmakeVfs()
{
return m_qmakeVfs;
}
void QmakeProject::destroyProFileReader(QtSupport::ProFileReader *reader)
{
delete reader;

View File

@@ -102,6 +102,8 @@ public:
/// \internal
ProFileGlobals *qmakeGlobals();
/// \internal
QMakeVfs *qmakeVfs();
/// \internal
void destroyProFileReader(QtSupport::ProFileReader *reader);
/// \internal