Commit 679d4e35 authored by Daniel Teske's avatar Daniel Teske

QmakeProject parsing: Move code from gui thread to parser threads

Change-Id: I05c1ec01a2c1ae4017ad2d09b07aa87854e3f118
Reviewed-by: default avatarTobias Hunger <tobias.hunger@theqtcompany.com>
parent c6180467
......@@ -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,
const QList<QList<VariableAndVPathInformation>> &variableAndVPathInformation)
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);
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;
}
}
while (ait != aend) {
result.append(*ait);
++ait;
}
while (bit != bend) {
result.append(*bit);
++bit;
}
return result;
}
EvalResult *QmakeProFileNode::evaluate(const EvalInput &input)
{
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();
return exactOk ? EvalOk : cumulOk ? EvalPartial : EvalFail;
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 EvalFail;
return result;
}
void QmakeProFileNode::asyncEvaluate(QFutureInterface<EvalResult> &fi)
void QmakeProFileNode::asyncEvaluate(QFutureInterface<EvalResult *> &fi, EvalInput input)
{
EvalResult evalResult = evaluate();
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);