diff options
| author | Christian Kandeler <christian.kandeler@digia.com> | 2013-06-14 10:57:38 +0200 |
|---|---|---|
| committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2013-06-18 10:57:25 +0200 |
| commit | b1d926024ddded2a43cc182c2d97839bb528def4 (patch) | |
| tree | fe9992446242f7aa25fe1e8c2e8875b8da86dbfe | |
| parent | 1d5c5e16a582401f5d1af299f95b57936db84593 (diff) | |
| download | qbs-b1d926024ddded2a43cc182c2d97839bb528def4.tar.gz | |
Some minor improvements to the Error class.
- Rename "Error" to "ErrorInfo", to make clear that this class conveys
information about errors, including that there might not actually be
one.
- Rename "ErrorData" to "ErrorItem", to make clear that these are parts
of an aggregate structure.
- Introduce ErrorInfo::hasError() for quick checking of whether an error
occurred.
Change-Id: Icea6ed5240d6d14bd30e9cea189c6babd7004792
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
56 files changed, 296 insertions, 281 deletions
diff --git a/src/app/config/configcommandexecutor.cpp b/src/app/config/configcommandexecutor.cpp index dcba2da9a..d95766a82 100644 --- a/src/app/config/configcommandexecutor.cpp +++ b/src/app/config/configcommandexecutor.cpp @@ -117,7 +117,7 @@ void ConfigCommandExecutor::exportSettings(const QString &filename) { QFile file(filename); if (!file.open(QFile::Truncate | QFile::WriteOnly | QFile::Text)) { - throw Error(tr("Could not open file '%1' for writing: %2") + throw ErrorInfo(tr("Could not open file '%1' for writing: %2") .arg(QDir::toNativeSeparators(filename), file.errorString())); } QTextStream stream(&file); @@ -130,7 +130,7 @@ void ConfigCommandExecutor::importSettings(const QString &filename) { QFile file(filename); if (!file.open(QFile::ReadOnly | QFile::Text)) { - throw Error(tr("Could not open file '%1' for reading: %2") + throw ErrorInfo(tr("Could not open file '%1' for reading: %2") .arg(QDir::toNativeSeparators(filename), file.errorString())); } // Remove all current settings diff --git a/src/app/config/configcommandlineparser.cpp b/src/app/config/configcommandlineparser.cpp index 2cdc5d428..b21561e6a 100644 --- a/src/app/config/configcommandlineparser.cpp +++ b/src/app/config/configcommandlineparser.cpp @@ -43,7 +43,7 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine) QStringList args = commandLine; if (args.isEmpty()) - throw Error(Tr::tr("No parameters supplied.")); + throw ErrorInfo(Tr::tr("No parameters supplied.")); if (args.count() == 1 && (args.first() == QLatin1String("--help") || args.first() == QLatin1String("-h"))) { m_helpRequested = true; @@ -61,16 +61,16 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine) } else if (arg == "import") { setCommand(ConfigCommand::CfgImport); } else { - throw Error("Unknown option for config command."); + throw ErrorInfo("Unknown option for config command."); } } switch (command().command) { case ConfigCommand::CfgNone: if (args.isEmpty()) - throw Error(Tr::tr("No parameters supplied.")); + throw ErrorInfo(Tr::tr("No parameters supplied.")); if (args.count() > 2) - throw Error("Too many arguments."); + throw ErrorInfo("Too many arguments."); m_command.varNames << args.first(); if (args.count() == 1) { setCommand(ConfigCommand::CfgGet); @@ -81,17 +81,17 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine) break; case ConfigCommand::CfgUnset: if (args.isEmpty()) - throw Error("Need name of variable to unset."); + throw ErrorInfo("Need name of variable to unset."); m_command.varNames = args; break; case ConfigCommand::CfgExport: if (args.count() != 1) - throw Error("Need name of file to which to export."); + throw ErrorInfo("Need name of file to which to export."); m_command.fileName = args.first(); break; case ConfigCommand::CfgImport: if (args.count() != 1) - throw Error("Need name of file from which to import."); + throw ErrorInfo("Need name of file from which to import."); m_command.fileName = args.first(); break; case ConfigCommand::CfgList: @@ -105,7 +105,7 @@ void ConfigCommandLineParser::parse(const QStringList &commandLine) void ConfigCommandLineParser::setCommand(ConfigCommand::Command command) { if (m_command.command != ConfigCommand::CfgNone) - throw Error("You cannot specify more than one command."); + throw ErrorInfo("You cannot specify more than one command."); m_command.command = command; } diff --git a/src/app/config/configmain.cpp b/src/app/config/configmain.cpp index de04e26be..3000bddb9 100644 --- a/src/app/config/configmain.cpp +++ b/src/app/config/configmain.cpp @@ -55,7 +55,7 @@ int main(int argc, char *argv[]) return EXIT_SUCCESS; } ConfigCommandExecutor(settings.data()).execute(parser.command()); - } catch (const qbs::Error &e) { + } catch (const qbs::ErrorInfo &e) { qbsError() << e.toString(); parser.printUsage(); return EXIT_FAILURE; diff --git a/src/app/detect-toolchains/main.cpp b/src/app/detect-toolchains/main.cpp index 14e4f630e..2e75edcec 100644 --- a/src/app/detect-toolchains/main.cpp +++ b/src/app/detect-toolchains/main.cpp @@ -62,7 +62,7 @@ int main(int argc, char **argv) try { probe(settings.data()); return EXIT_SUCCESS; - } catch (const qbs::Error &error) { + } catch (const qbs::ErrorInfo &error) { qbsError() << Tr::tr("Probing for toolchains failed: %1").arg(error.toString()); return EXIT_FAILURE; } diff --git a/src/app/qbs-setup-qt/main.cpp b/src/app/qbs-setup-qt/main.cpp index c3181ea3d..dd7f859fb 100644 --- a/src/app/qbs-setup-qt/main.cpp +++ b/src/app/qbs-setup-qt/main.cpp @@ -113,7 +113,7 @@ int main(int argc, char *argv[]) } printUsage(appName); return EXIT_FAILURE; - } catch (const Error &e) { + } catch (const ErrorInfo &e) { qbsError() << Tr::tr("%1: %2").arg(appName, e.toString()); return EXIT_FAILURE; } diff --git a/src/app/qbs-setup-qt/setupqt.cpp b/src/app/qbs-setup-qt/setupqt.cpp index 703adc86e..5e45af5b4 100644 --- a/src/app/qbs-setup-qt/setupqt.cpp +++ b/src/app/qbs-setup-qt/setupqt.cpp @@ -101,7 +101,7 @@ static QMap<QByteArray, QByteArray> qmakeQueryOutput(const QString &qmakePath) QProcess qmakeProcess; qmakeProcess.start(qmakePath, QStringList() << "-query"); if (!qmakeProcess.waitForStarted()) - throw Error(SetupQt::tr("%1 cannot be started.").arg(qmakePath)); + throw ErrorInfo(SetupQt::tr("%1 cannot be started.").arg(qmakePath)); qmakeProcess.waitForFinished(); const QByteArray output = qmakeProcess.readAllStandardOutput(); @@ -184,7 +184,7 @@ QtEnvironment SetupQt::fetchEnvironment(const QString &qmakePath) mkspecsBasePath = queryOutput.value("QT_INSTALL_DATA") + "/mkspecs"; if (!QFile::exists(mkspecsBasePath)) - throw Error(tr("Cannot extract the mkspecs directory.")); + throw ErrorInfo(tr("Cannot extract the mkspecs directory.")); const QByteArray qconfigContent = readFileContent(mkspecsBasePath + "/qconfig.pri"); qtEnvironment.qtMajorVersion = configVariable(qconfigContent, "QT_MAJOR_VERSION").toInt(); @@ -214,7 +214,7 @@ QtEnvironment SetupQt::fetchEnvironment(const QString &qmakePath) if (qtEnvironment.configItems.contains("qt_framework")) qtEnvironment.frameworkBuild = true; else if (!qtEnvironment.configItems.contains("qt_no_framework")) - throw Error(tr("could not determine whether Qt is a frameworks build")); + throw ErrorInfo(tr("could not determine whether Qt is a frameworks build")); } // determine whether we have a static build @@ -230,7 +230,7 @@ QtEnvironment SetupQt::fetchEnvironment(const QString &qmakePath) const QStringList coreLibFiles = libdir.entryList(QStringList(QLatin1String("*Core*")), QDir::Files); if (coreLibFiles.isEmpty()) - throw Error(tr("Could not determine whether Qt is a static build.")); + throw ErrorInfo(tr("Could not determine whether Qt is a static build.")); foreach (const QString &fileName, coreLibFiles) { if (QLibrary::isLibrary(qtEnvironment.libraryPath + QLatin1Char('/') + fileName)) { qtEnvironment.staticBuild = false; @@ -253,7 +253,7 @@ QtEnvironment SetupQt::fetchEnvironment(const QString &qmakePath) } if (!QFileInfo(qtEnvironment.mkspecPath).exists()) - throw Error(tr("mkspec '%1' does not exist").arg(qtEnvironment.mkspecPath)); + throw ErrorInfo(tr("mkspec '%1' does not exist").arg(qtEnvironment.mkspecPath)); qtEnvironment.mkspecPath = QDir::toNativeSeparators(qtEnvironment.mkspecPath); return qtEnvironment; @@ -323,7 +323,7 @@ void SetupQt::saveToQbsSettings(const QString &qtVersionName, const QtEnvironmen } if (osxVersion.isEmpty()) - throw Error(tr("error reading qconfig.h; could not determine whether Qt is using Cocoa or Carbon")); + throw ErrorInfo(tr("error reading qconfig.h; could not determine whether Qt is using Cocoa or Carbon")); } } diff --git a/src/app/qbs/commandlinefrontend.cpp b/src/app/qbs/commandlinefrontend.cpp index b6f616c80..95a3b56f2 100644 --- a/src/app/qbs/commandlinefrontend.cpp +++ b/src/app/qbs/commandlinefrontend.cpp @@ -75,7 +75,7 @@ void CommandLineFrontend::start() case RunCommandType: case ShellCommandType: if (m_parser.products().count() > 1) { - throw Error(Tr::tr("Invalid use of command '%1': Cannot use more than one " + throw ErrorInfo(Tr::tr("Invalid use of command '%1': Cannot use more than one " "product.\nUsage: %2") .arg(m_parser.commandName(), m_parser.commandDescription())); } @@ -87,7 +87,7 @@ void CommandLineFrontend::start() QString error = Tr::tr("Invalid use of command '%1': There can be only one " "build configuration.\n").arg(m_parser.commandName()); error += Tr::tr("Usage: %1").arg(m_parser.commandDescription()); - throw Error(error); + throw ErrorInfo(error); } break; default: @@ -110,9 +110,8 @@ void CommandLineFrontend::start() params.setRestoreBehavior(SetupProjectParameters::RestoreOnly); foreach (const QVariantMap &buildConfig, m_parser.buildConfigurations()) { params.setBuildConfiguration(buildConfig); - - Error err = params.expandBuildConfiguration(m_settings); - if (!err.entries().isEmpty()) + const ErrorInfo err = params.expandBuildConfiguration(m_settings); + if (err.hasError()) throw err; SetupProjectJob * const job = Project::setupProject(params, @@ -131,7 +130,7 @@ void CommandLineFrontend::start() */ if (m_parser.showProgress() && resolvingMultipleProjects()) m_observer->initialize(tr("Setting up projects"), m_resolveJobs.count()); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { qbsError() << error.toString(); if (m_buildJobs.isEmpty() && m_resolveJobs.isEmpty()) qApp->exit(EXIT_FAILURE); @@ -276,7 +275,7 @@ CommandLineFrontend::ProductMap CommandLineFrontend::productsToUse() const foreach (const QString &productName, m_parser.products()) { if (!productNames.contains(productName)) - throw Error(Tr::tr("No such product '%1'.").arg(productName)); + throw ErrorInfo(Tr::tr("No such product '%1'.").arg(productName)); } return products; @@ -286,7 +285,7 @@ void CommandLineFrontend::handleProjectsResolved() { try { if (m_canceled) - throw Error(Tr::tr("Execution canceled.")); + throw ErrorInfo(Tr::tr("Execution canceled.")); switch (m_parser.command()) { case ResolveCommandType: qApp->quit(); @@ -327,7 +326,7 @@ void CommandLineFrontend::handleProjectsResolved() case HelpCommandType: Q_ASSERT_X(false, Q_FUNC_INFO, "Impossible."); } - } catch (const Error &error) { + } catch (const ErrorInfo &error) { qbsError() << error.toString(); qApp->exit(EXIT_FAILURE); } @@ -397,13 +396,13 @@ int CommandLineFrontend::runTarget() const QString executableFilePath = project.targetExecutable(productToRun, m_parser.installOptions()); if (executableFilePath.isEmpty()) { - throw Error(Tr::tr("Cannot run: Product '%1' is not an application.") + throw ErrorInfo(Tr::tr("Cannot run: Product '%1' is not an application.") .arg(productToRun.name())); } RunEnvironment runEnvironment = project.getRunEnvironment(productToRun, QProcessEnvironment::systemEnvironment(), m_settings); return runEnvironment.runTarget(executableFilePath, m_parser.runArgs()); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { qbsError() << error.toString(); return EXIT_FAILURE; } @@ -456,7 +455,7 @@ void CommandLineFrontend::checkForExactlyOneProduct() { if (m_parser.products().count() == 0 && m_projects.first().projectData().products().count() > 1) { - throw Error(Tr::tr("Ambiguous use of command '%1': No product given for project " + throw ErrorInfo(Tr::tr("Ambiguous use of command '%1': No product given for project " "with more than one product.\nUsage: %2") .arg(m_parser.commandName(), m_parser.commandDescription())); } diff --git a/src/app/qbs/commandlinefrontend.h b/src/app/qbs/commandlinefrontend.h index d00112931..5c913f957 100644 --- a/src/app/qbs/commandlinefrontend.h +++ b/src/app/qbs/commandlinefrontend.h @@ -40,7 +40,7 @@ namespace qbs { class AbstractJob; class ConsoleProgressObserver; -class Error; +class ErrorInfo; class ProcessResult; class Settings; diff --git a/src/app/qbs/main.cpp b/src/app/qbs/main.cpp index 788a75fbc..5a404bde6 100644 --- a/src/app/qbs/main.cpp +++ b/src/app/qbs/main.cpp @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) app.setCommandLineFrontend(&clFrontend); QTimer::singleShot(0, &clFrontend, SLOT(start())); return app.exec(); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { qbsError() << error.toString(); return EXIT_FAILURE; } diff --git a/src/app/qbs/parser/command.cpp b/src/app/qbs/parser/command.cpp index 998466cdb..e9624c5c6 100644 --- a/src/app/qbs/parser/command.cpp +++ b/src/app/qbs/parser/command.cpp @@ -50,7 +50,7 @@ void Command::parse(QStringList &input) parseOptions(input); parseMore(input); if (!input.isEmpty()) { - throw Error(Tr::tr("Invalid use of command '%1': Extraneous input '%2'.\nUsage: %3") + throw ErrorInfo(Tr::tr("Invalid use of command '%1': Extraneous input '%2'.\nUsage: %3") .arg(representation(), input.join(QLatin1String(" ")), longDescription())); } } @@ -65,7 +65,7 @@ void Command::addAllToAdditionalArguments(QStringList &input) void Command::addOneToAdditionalArguments(const QString &argument) { if (argument.startsWith(QLatin1Char('-'))) { - throw Error(Tr::tr("Invalid use of command '%1': Encountered option '%2', expected a " + throw ErrorInfo(Tr::tr("Invalid use of command '%1': Encountered option '%2', expected a " "build variant or property.\nUsage: %3") .arg(representation(), argument, longDescription())); } @@ -91,7 +91,7 @@ void Command::parseOptions(QStringList &input) break; input.removeFirst(); if (optionString.count() == 1) { - throw Error(Tr::tr("Invalid use of command '%1': Empty options are not allowed.\n" + throw ErrorInfo(Tr::tr("Invalid use of command '%1': Empty options are not allowed.\n" "Usage: %2").arg(representation(), longDescription())); } @@ -110,7 +110,7 @@ void Command::parseOptions(QStringList &input) continue; } if (usedOptions.contains(option) && !option->canAppearMoreThanOnce()) { - throw Error(Tr::tr("Invalid use of command '%1': Option '%2' cannot appear " + throw ErrorInfo(Tr::tr("Invalid use of command '%1': Option '%2' cannot appear " "more than once.\nUsage: %3") .arg(representation(), optionString, longDescription())); } @@ -120,7 +120,7 @@ void Command::parseOptions(QStringList &input) break; } if (!matchFound) { - throw Error(Tr::tr("Invalid use of command '%1': Unknown option '%2'.\nUsage: %3") + throw ErrorInfo(Tr::tr("Invalid use of command '%1': Unknown option '%2'.\nUsage: %3") .arg(representation(), optionString, longDescription())); } } @@ -469,7 +469,7 @@ void HelpCommand::parseMore(QStringList &input) if (input.isEmpty()) return; if (input.count() > 1) { - throw Error(Tr::tr("Invalid use of command '%1': Cannot describe more than one command.\n" + throw ErrorInfo(Tr::tr("Invalid use of command '%1': Cannot describe more than one command.\n" "Usage: %2").arg(representation(), longDescription())); } m_command = input.takeFirst(); diff --git a/src/app/qbs/parser/commandlineoption.cpp b/src/app/qbs/parser/commandlineoption.cpp index 2fc88147a..358ed312a 100644 --- a/src/app/qbs/parser/commandlineoption.cpp +++ b/src/app/qbs/parser/commandlineoption.cpp @@ -49,7 +49,7 @@ void CommandLineOption::parse(CommandType command, const QString &representation QString CommandLineOption::getArgument(const QString &representation, QStringList &input) { if (input.isEmpty()) { - throw Error(Tr::tr("Invalid use of option '%1': Missing argument.\nUsage: %2") + throw ErrorInfo(Tr::tr("Invalid use of option '%1': Missing argument.\nUsage: %2") .arg(representation, description(command()))); } return input.takeFirst(); @@ -150,7 +150,7 @@ void JobsOption::doParse(const QString &representation, QStringList &input) bool stringOk; m_jobCount = jobCountString.toInt(&stringOk); if (!stringOk || m_jobCount <= 0) - throw Error(Tr::tr("Invalid use of option '%1': Illegal job count '%2'.\nUsage: %3") + throw ErrorInfo(Tr::tr("Invalid use of option '%1': Illegal job count '%2'.\nUsage: %3") .arg(representation, jobCountString, description(command()))); } @@ -219,12 +219,12 @@ void StringListOption::doParse(const QString &representation, QStringList &input { m_arguments = getArgument(representation, input).split(QLatin1Char(',')); if (m_arguments.isEmpty()) { - throw Error(Tr::tr("Invalid use of option '%1': Argument list must not be empty.\n" + throw ErrorInfo(Tr::tr("Invalid use of option '%1': Argument list must not be empty.\n" "Usage: %2").arg(representation, description(command()))); } foreach (const QString &element, m_arguments) { if (element.isEmpty()) { - throw Error(Tr::tr("Invalid use of option '%1': Argument list must not contain " + throw ErrorInfo(Tr::tr("Invalid use of option '%1': Argument list must not contain " "empty elements.\nUsage: %2") .arg(representation, description(command()))); } @@ -304,7 +304,7 @@ void LogLevelOption::doParse(const QString &representation, QStringList &input) return; } } - throw Error(Tr::tr("Invalid use of option '%1': Unknown log level '%2'.\nUsage: %3") + throw ErrorInfo(Tr::tr("Invalid use of option '%1': Unknown log level '%2'.\nUsage: %3") .arg(representation, levelString, description(command()))); } @@ -362,7 +362,7 @@ QString InstallRootOption::longRepresentation() const void InstallRootOption::doParse(const QString &representation, QStringList &input) { if (input.isEmpty()) { - throw Error(Tr::tr("Invalid use of option '%1: Argument expected.\n" + throw ErrorInfo(Tr::tr("Invalid use of option '%1: Argument expected.\n" "Usage: %2").arg(representation, description(command()))); } const QString installRoot = input.takeFirst(); diff --git a/src/app/qbs/parser/commandlineparser.cpp b/src/app/qbs/parser/commandlineparser.cpp index b45e98344..551f8f4dc 100644 --- a/src/app/qbs/parser/commandlineparser.cpp +++ b/src/app/qbs/parser/commandlineparser.cpp @@ -113,7 +113,7 @@ void CommandLineParser::printHelp() const stream << commandToDescribe->longDescription(); } else if (!QbsTool::tryToRunTool(helpCommand->commandToDescribe(), QStringList(QLatin1String("--help")))) { - throw Error(Tr::tr("No such command '%1'.\n%2") + throw ErrorInfo(Tr::tr("No such command '%1'.\n%2") .arg(helpCommand->commandToDescribe(), d->generalHelp())); } } @@ -308,7 +308,7 @@ bool CommandLineParser::parseCommandLine(const QStringList &args, Settings *sett try { d->doParse(); return true; - } catch (const Error &error) { + } catch (const ErrorInfo &error) { qbsError() << error.toString(); return false; } @@ -425,13 +425,13 @@ void CommandLineParser::CommandLineParserPrivate::setupProjectFile() const QFileInfo projectFileInfo(projectFilePath); if (!projectFileInfo.exists()) - throw Error(Tr::tr("Project file '%1' cannot be found.").arg(projectFilePath)); + throw ErrorInfo(Tr::tr("Project file '%1' cannot be found.").arg(projectFilePath)); if (projectFileInfo.isRelative()) projectFilePath = projectFileInfo.absoluteFilePath(); if (projectFileInfo.isFile()) return; if (!projectFileInfo.isDir()) - throw Error(Tr::tr("Project file '%1' has invalid type.").arg(projectFilePath)); + throw ErrorInfo(Tr::tr("Project file '%1' has invalid type.").arg(projectFilePath)); // TODO: Remove check for '.qbp' in 1.1 const QStringList namePatterns = QStringList() @@ -447,10 +447,10 @@ void CommandLineParser::CommandLineParserPrivate::setupProjectFile() } else { error = Tr::tr("No project file found in directory '%1'.").arg(projectFilePath); } - throw Error(error); + throw ErrorInfo(error); } if (actualFileNames.count() > 1) { - throw Error(Tr::tr("More than one project file found in directory '%1'.") + throw ErrorInfo(Tr::tr("More than one project file found in directory '%1'.") .arg(projectFilePath)); } projectFilePath.append(QLatin1Char('/')).append(actualFileNames.first()); diff --git a/src/lib/api/internaljobs.cpp b/src/lib/api/internaljobs.cpp index 7b9f9b3b6..b0eb5aee9 100644 --- a/src/lib/api/internaljobs.cpp +++ b/src/lib/api/internaljobs.cpp @@ -123,7 +123,7 @@ void InternalJob::storeBuildGraph(const TopLevelProjectConstPtr &project) { try { project->store(logger()); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { logger().printWarning(error); } } @@ -147,7 +147,7 @@ void InternalSetupProjectJob::resolve(const SetupProjectParameters ¶meters) QTimer::singleShot(0, this, SLOT(start())); } -void InternalSetupProjectJob::reportError(const Error &error) +void InternalSetupProjectJob::reportError(const ErrorInfo &error) { setError(error); QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection, @@ -176,7 +176,7 @@ void InternalSetupProjectJob::doResolve() { try { execute(); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { setError(error); } QMutexLocker locker(&m_runMutex); @@ -312,8 +312,7 @@ void InternalBuildJob::build(const TopLevelProjectPtr &project, void InternalBuildJob::handleFinished() { - if (m_executor->hasError()) - setError(m_executor->error()); + setError(m_executor->error()); project()->buildData->evaluationContext.clear(); storeBuildGraph(); m_executor->deleteLater(); @@ -355,7 +354,7 @@ void InternalCleanJob::doClean() try { ArtifactCleaner cleaner(logger(), observer()); cleaner.cleanup(project(), products(), m_options); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { setError(error); } storeBuildGraph(); @@ -397,7 +396,7 @@ void InternalInstallJob::doInstall() { try { ProductInstaller(m_project, m_products, m_options, observer(), logger()).install(); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { setError(error); } } diff --git a/src/lib/api/internaljobs.h b/src/lib/api/internaljobs.h index 23676f84b..0c1855082 100644 --- a/src/lib/api/internaljobs.h +++ b/src/lib/api/internaljobs.h @@ -59,8 +59,7 @@ class InternalJob : public QObject friend class JobObserver; public: void cancel(); - Error error() const { return m_error; } - bool hasError() const { return !error().entries().isEmpty(); } + ErrorInfo error() const { return m_error; } Logger logger() const { return m_logger; } bool timed() const { return m_timed; } @@ -69,7 +68,7 @@ protected: explicit InternalJob(const Logger &logger, QObject *parent = 0); JobObserver *observer() const { return m_observer; } - void setError(const Error &error) { m_error = error; } + void setError(const ErrorInfo &error) { m_error = error; } void setTimed(bool timed) { m_timed = timed; } void storeBuildGraph(const TopLevelProjectConstPtr &project); @@ -80,7 +79,7 @@ signals: void taskProgress(int value, Internal::InternalJob *job); private: - Error m_error; + ErrorInfo m_error; JobObserver * const m_observer; Logger m_logger; bool m_timed; @@ -95,7 +94,7 @@ public: ~InternalSetupProjectJob(); void resolve(const SetupProjectParameters ¶meters); - void reportError(const Error &error); + void reportError(const ErrorInfo &error); TopLevelProjectPtr project() const; diff --git a/src/lib/api/jobs.cpp b/src/lib/api/jobs.cpp index 47bda7191..c139ee215 100644 --- a/src/lib/api/jobs.cpp +++ b/src/lib/api/jobs.cpp @@ -125,7 +125,7 @@ AbstractJob::~AbstractJob() /*! * \brief Returns the error which caused this operation to fail, if it did fail. */ -Error AbstractJob::error() const +ErrorInfo AbstractJob::error() const { return internalJob()->error(); } @@ -163,7 +163,7 @@ void AbstractJob::handleFinished() { QBS_ASSERT(m_state != StateFinished, return); m_state = StateFinished; - emit finished(!hasError(), this); + emit finished(!error().hasError(), this); } @@ -198,7 +198,7 @@ void SetupProjectJob::resolve(const SetupProjectParameters ¶meters) job->resolve(parameters); } -void SetupProjectJob::reportError(const Error &error) +void SetupProjectJob::reportError(const ErrorInfo &error) { InternalSetupProjectJob * const job = qobject_cast<InternalSetupProjectJob *>(internalJob()); job->reportError(error); diff --git a/src/lib/api/jobs.h b/src/lib/api/jobs.h index 791ad2af7..f1e85c46b 100644 --- a/src/lib/api/jobs.h +++ b/src/lib/api/jobs.h @@ -60,8 +60,7 @@ public: enum State { StateRunning, StateCanceling, StateFinished }; State state() const { return m_state; } - Error error() const; - bool hasError() const { return !error().entries().isEmpty(); } + ErrorInfo error() const; void cancel(); @@ -98,7 +97,7 @@ private: SetupProjectJob(const Internal::Logger &logger, QObject *parent); void resolve(const SetupProjectParameters ¶meters); - void reportError(const Error &error); + void reportError(const ErrorInfo &error); }; class QBS_EXPORT BuildJob : public AbstractJob diff --git a/src/lib/api/project.cpp b/src/lib/api/project.cpp index f496f41e6..6ee129150 100644 --- a/src/lib/api/project.cpp +++ b/src/lib/api/project.cpp @@ -79,7 +79,7 @@ static void loadPlugins(const QStringList &_pluginPaths, const Logger &logger) } ScannerPluginManager::instance()->loadPlugins(pluginPaths, logger); - qRegisterMetaType<Error>("qbs::Error"); + qRegisterMetaType<ErrorInfo>("qbs::Error"); qRegisterMetaType<ProcessResult>("qbs::ProcessResult"); qRegisterMetaType<InternalJob *>("Internal::InternalJob *"); pluginsLoaded = true; @@ -305,7 +305,7 @@ SetupProjectJob *Project::setupProject(const SetupProjectParameters ¶meters, try { loadPlugins(parameters.pluginPaths(), logger); job->resolve(parameters); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { // Throwing from here would complicate the API, so let's report the error the same way // as all others, via AbstractJob::error(). job->reportError(error); diff --git a/src/lib/buildgraph/abstractcommandexecutor.h b/src/lib/buildgraph/abstractcommandexecutor.h index e372f6440..2bdecd939 100644 --- a/src/lib/buildgraph/abstractcommandexecutor.h +++ b/src/lib/buildgraph/abstractcommandexecutor.h @@ -39,7 +39,7 @@ class QScriptEngine; QT_END_NAMESPACE namespace qbs { -class Error; +class ErrorInfo; namespace Internal { class AbstractCommand; @@ -61,7 +61,7 @@ public slots: signals: void reportCommandDescription(const QString &highlight, const QString &message); - void error(const qbs::Error &err); + void error(const qbs::ErrorInfo &err); void finished(); protected: diff --git a/src/lib/buildgraph/artifactcleaner.cpp b/src/lib/buildgraph/artifactcleaner.cpp index 5fc5deace..d1b76ca69 100644 --- a/src/lib/buildgraph/artifactcleaner.cpp +++ b/src/lib/buildgraph/artifactcleaner.cpp @@ -79,7 +79,7 @@ static void removeArtifactFromDisk(Artifact *artifact, bool dryRun, const Logger invalidateArtifactTimestamp(artifact); QString errorMessage; if (!removeFileRecursion(fileInfo, &errorMessage)) - throw Error(errorMessage); + throw ErrorInfo(errorMessage); } class CleanupVisitor : public ArtifactVisitor @@ -113,7 +113,7 @@ private: } try { removeArtifactFromDisk(artifact, m_options.dryRun(), m_logger); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { if (!m_options.keepGoing()) throw; m_logger.printWarning(error); @@ -161,7 +161,7 @@ void ArtifactCleaner::cleanup(const TopLevelProjectPtr &project, m_observer->incrementProgressValue(); if (m_hasError) - throw Error(Tr::tr("Failed to remove some files.")); + throw ErrorInfo(Tr::tr("Failed to remove some files.")); m_observer->setFinished(); } @@ -180,7 +180,7 @@ void ArtifactCleaner::removeEmptyDirectories(const QString &rootDir, const Clean if (subTreeIsEmpty) { printRemovalMessage(rootDir, options.dryRun(), m_logger); if (!QDir::root().rmdir(rootDir)) { - Error error(Tr::tr("Failure to remove empty directory '%1'.").arg(rootDir)); + ErrorInfo error(Tr::tr("Failure to remove empty directory '%1'.").arg(rootDir)); if (!options.keepGoing()) throw error; m_logger.printWarning(error); diff --git a/src/lib/buildgraph/automoc.cpp b/src/lib/buildgraph/automoc.cpp index 1ff61c993..b81444a55 100644 --- a/src/lib/buildgraph/automoc.cpp +++ b/src/lib/buildgraph/automoc.cpp @@ -82,7 +82,7 @@ void AutoMoc::setScanResultCache(ScanResultCache *scanResultCache) void AutoMoc::apply(const ResolvedProductPtr &product) { if (scanners().isEmpty()) - throw Error("C++ scanner cannot be loaded."); + throw ErrorInfo("C++ scanner cannot be loaded."); Artifact *pluginMetaDataFile = 0; Artifact *pchFile = 0; diff --git a/src/lib/buildgraph/buildgraph.cpp b/src/lib/buildgraph/buildgraph.cpp index 730ea07a4..8fa790bf2 100644 --- a/src/lib/buildgraph/buildgraph.cpp +++ b/src/lib/buildgraph/buildgraph.cpp @@ -388,7 +388,7 @@ void insertArtifact(const ResolvedProductPtr &product, Artifact *artifact, const if (lookupArtifact(p, artifact->filePath())) pl.append(QString(" - %1 \n").arg(p->name)); } - throw Error(QString ("BUG: already inserted in this project: %1\n%2") + throw ErrorInfo(QString ("BUG: already inserted in this project: %1\n%2") .arg(artifact->filePath()).arg(pl)); } } @@ -493,7 +493,7 @@ BuildGraphLoadResult BuildGraphLoader::load(const SetupProjectParameters ¶me m_logger.qbsDebug() << "[BG] trying to load: " << buildGraphFilePath; try { pool.load(buildGraphFilePath); - } catch (const Error &loadError) { + } catch (const ErrorInfo &loadError) { if (parameters.restoreBehavior() == SetupProjectParameters::RestoreOnly) throw loadError; m_logger.qbsInfo() << loadError.toString(); @@ -504,7 +504,7 @@ BuildGraphLoadResult BuildGraphLoader::load(const SetupProjectParameters ¶me const QString message = Tr::tr("Cannot use stored build graph at '%1':" "Incompatible project configuration.").arg(buildGraphFilePath); if (parameters.restoreBehavior() == SetupProjectParameters::RestoreOnly) - throw Error(message); + throw ErrorInfo(message); m_logger.qbsInfo() << message; return m_result; } @@ -524,7 +524,7 @@ BuildGraphLoadResult BuildGraphLoader::load(const SetupProjectParameters ¶me QDir::toNativeSeparators(parameters.projectFilePath())); if (!parameters.ignoreDifferentProjectFilePath()) { errorMessage += Tr::tr("Aborting."); - throw Error(errorMessage); + throw ErrorInfo(errorMessage); } // Okay, let's assume it's the same project anyway (the source dir might have moved). diff --git a/src/lib/buildgraph/cycledetector.cpp b/src/lib/buildgraph/cycledetector.cpp index 28e027d93..bb5d0bf38 100644 --- a/src/lib/buildgraph/cycledetector.cpp +++ b/src/lib/buildgraph/cycledetector.cpp @@ -54,7 +54,7 @@ void CycleDetector::visitProject(const ResolvedProjectConstPtr &project) void CycleDetector::visitArtifact(Artifact *artifact) { if (Q_UNLIKELY(m_artifactsInCurrentPath.contains(artifact))) { - Error error(Tr::tr("Cycle in build graph detected.")); + ErrorInfo error(Tr::tr("Cycle in build graph detected.")); foreach (const Artifact * const a, cycle(artifact)) error.append(a->filePath()); throw error; diff --git a/src/lib/buildgraph/executor.cpp b/src/lib/buildgraph/executor.cpp index 4b00e1008..11cdd9aad 100644 --- a/src/lib/buildgraph/executor.cpp +++ b/src/lib/buildgraph/executor.cpp @@ -155,7 +155,7 @@ void Executor::build() { try { doBuild(); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { m_error = e; QTimer::singleShot(0, this, SLOT(finish())); } @@ -636,7 +636,7 @@ void Executor::doSanityChecks() } } -void Executor::handleError(const Error &error) +void Executor::handleError(const ErrorInfo &error) { m_error = error; if (m_processingJobs.isEmpty()) @@ -656,8 +656,8 @@ void Executor::addExecutorJobs(int jobNumber) this, SIGNAL(reportCommandDescription(QString,QString))); connect(job, SIGNAL(reportProcessResult(qbs::ProcessResult)), this, SIGNAL(reportProcessResult(qbs::ProcessResult))); - connect(job, SIGNAL(error(qbs::Error)), - this, SLOT(onProcessError(qbs::Error))); + connect(job, SIGNAL(error(qbs::ErrorInfo)), + this, SLOT(onProcessError(qbs::ErrorInfo))); connect(job, SIGNAL(success()), this, SLOT(onProcessSuccess())); } } @@ -667,7 +667,7 @@ void Executor::runAutoMoc() bool autoMocApplied = false; foreach (const ResolvedProductPtr &product, m_productsToBuild) { if (m_progressObserver && m_progressObserver->canceled()) - throw Error(Tr::tr("Build canceled%1.").arg(configString())); + throw ErrorInfo(Tr::tr("Build canceled%1.").arg(configString())); // HACK call the automoc thingy here only if we have use Qt/core module foreach (const ResolvedModuleConstPtr &m, product->modules) { if (m->name == "Qt/core") { @@ -685,11 +685,11 @@ void Executor::runAutoMoc() m_progressObserver->incrementProgressValue(m_mocEffort); } -void Executor::onProcessError(const qbs::Error &err) +void Executor::onProcessError(const qbs::ErrorInfo &err) { try { if (m_buildOptions.keepGoing()) { - Error fullWarning(err); + ErrorInfo fullWarning(err); fullWarning.prepend(Tr::tr("Ignoring the following errors on user request:")); m_logger.printWarning(fullWarning); } else { @@ -697,7 +697,7 @@ void Executor::onProcessError(const qbs::Error &err) } ExecutorJob * const job = qobject_cast<ExecutorJob *>(sender()); finishJob(job, false); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { handleError(error); } } @@ -720,7 +720,7 @@ void Executor::onProcessSuccess() } finishJob(job, true); - } catch (const Error &error) { + } catch (const ErrorInfo &error) { handleError(error); } } diff --git a/src/lib/buildgraph/executor.h b/src/lib/buildgraph/executor.h index 7a55adf64..e55909744 100644 --- a/src/lib/buildgraph/executor.h +++ b/src/lib/buildgraph/executor.h @@ -67,8 +67,7 @@ public: void setBuildOptions(const BuildOptions &buildOptions); void setProgressObserver(ProgressObserver *observer) { m_progressObserver = observer; } - Error error() const { return m_error; } - bool hasError() const { return !error().entries().isEmpty(); } + ErrorInfo error() const { return m_error; } signals: void reportCommandDescription(const QString &highlight, const QString &message); @@ -77,7 +76,7 @@ signals: void finished(); private slots: - void onProcessError(const qbs::Error &err); + void onProcessError(const qbs::ErrorInfo &err); void onProcessSuccess(); void finish(); @@ -103,7 +102,7 @@ private: void cancelJobs(); void setupProgressObserver(bool mocWillRun); void doSanityChecks(); - void handleError(const Error &error); + void handleError(const ErrorInfo &error); bool mustExecuteTransformer(const TransformerPtr &transformer) const; bool isUpToDate(Artifact *artifact) const; @@ -128,7 +127,7 @@ private: InputArtifactScannerContext *m_inputArtifactScanContext; AutoMoc *m_autoMoc; int m_mocEffort; - Error m_error; + ErrorInfo m_error; bool m_explicitlyCanceled; const bool m_doTrace; const bool m_doDebug; diff --git a/src/lib/buildgraph/executorjob.cpp b/src/lib/buildgraph/executorjob.cpp index dd785105b..44eb5cdb4 100644 --- a/src/lib/buildgraph/executorjob.cpp +++ b/src/lib/buildgraph/executorjob.cpp @@ -51,13 +51,13 @@ ExecutorJob::ExecutorJob(const Logger &logger, QObject *parent) this, SIGNAL(reportCommandDescription(QString,QString))); connect(m_processCommandExecutor, SIGNAL(reportProcessResult(qbs::ProcessResult)), this, SIGNAL(reportProcessResult(qbs::ProcessResult))); - connect(m_processCommandExecutor, SIGNAL(error(qbs::Error)), - this, SLOT(onCommandError(qbs::Error))); + connect(m_processCommandExecutor, SIGNAL(error(qbs::ErrorInfo)), + this, SLOT(onCommandError(qbs::ErrorInfo))); connect(m_processCommandExecutor, SIGNAL(finished()), SLOT(onCommandFinished())); connect(m_jsCommandExecutor, SIGNAL(reportCommandDescription(QString,QString)), this, SIGNAL(reportCommandDescription(QString,QString))); - connect(m_jsCommandExecutor, SIGNAL(error(qbs::Error)), - this, SLOT(onCommandError(qbs::Error))); + connect(m_jsCommandExecutor, SIGNAL(error(qbs::ErrorInfo)), + this, SLOT(onCommandError(qbs::ErrorInfo))); connect(m_jsCommandExecutor, SIGNAL(finished()), SLOT(onCommandFinished())); setInactive(); } @@ -131,7 +131,7 @@ void ExecutorJob::runNextCommand() m_currentCommandExecutor->start(m_transformer, command); } -void ExecutorJob::onCommandError(const Error &err) +void ExecutorJob::onCommandError(const ErrorInfo &err) { setInactive(); emit error(err); diff --git a/src/lib/buildgraph/executorjob.h b/src/lib/buildgraph/executorjob.h index 358271e36..9a5bb1ae4 100644 --- a/src/lib/buildgraph/executorjob.h +++ b/src/lib/buildgraph/executorjob.h @@ -67,12 +67,12 @@ public: signals: void reportCommandDescription(const QString &highlight, const QString &message); void reportProcessResult(const qbs::ProcessResult &result); - void error(const qbs::Error &error); + void error(const qbs::ErrorInfo &error); void success(); private slots: void runNextCommand(); - void onCommandError(const qbs::Error &err); + void onCommandError(const qbs::ErrorInfo &err); void onCommandFinished(); private: diff --git a/src/lib/buildgraph/jscommandexecutor.cpp b/src/lib/buildgraph/jscommandexecutor.cpp index 9a2cbfa4a..8444d4ceb 100644 --- a/src/lib/buildgraph/jscommandexecutor.cpp +++ b/src/lib/buildgraph/jscommandexecutor.cpp @@ -179,7 +179,7 @@ void JsCommandExecutor::onJavaScriptCommandFinished() logger().qbsDebug() << "JS code:\n" << jsCommand()->sourceCode(); QString msg = "Error while executing JavaScriptCommand:\n"; msg += result.errorMessage; - emit error(Error(msg, result.errorLocation)); + emit error(ErrorInfo(msg, result.errorLocation)); } emit finished(); } diff --git a/src/lib/buildgraph/processcommandexecutor.cpp b/src/lib/buildgraph/processcommandexecutor.cpp index 466ea5146..78f77c381 100644 --- a/src/lib/buildgraph/processcommandexecutor.cpp +++ b/src/lib/buildgraph/processcommandexecutor.cpp @@ -134,7 +134,7 @@ void ProcessCommandExecutor::doStart() responseFile.setAutoRemove(false); responseFile.setFileTemplate(QDir::tempPath() + "/qbsresp"); if (!responseFile.open()) { - emit error(Error(Tr::tr("Cannot create response file '%1'.") + emit error(ErrorInfo(Tr::tr("Cannot create response file '%1'.") .arg(responseFile.fileName()))); return; } @@ -174,7 +174,7 @@ QString ProcessCommandExecutor::filterProcessOutput(const QByteArray &_output, QScriptValue filterFunction = scriptEngine()->evaluate("var f = " + filterFunctionSource + "; f"); if (!filterFunction.isFunction()) { - emit error(Error(Tr::tr("Error in filter function: %1.\n%2") + emit error(ErrorInfo(Tr::tr("Error in filter function: %1.\n%2") .arg(filterFunctionSource, filterFunction.toString()))); return output; } @@ -183,7 +183,7 @@ QString ProcessCommandExecutor::filterProcessOutput(const QByteArray &_output, outputArg.setProperty(0, scriptEngine()->toScriptValue(output)); QScriptValue filteredOutput = filterFunction.call(scriptEngine()->undefinedValue(), outputArg); if (filteredOutput.isError()) { - emit error(Error(Tr::tr("Error when calling output filter function: %1") + emit error(ErrorInfo(Tr::tr("Error when calling output filter function: %1") .arg(filteredOutput.toString()))); return output; } @@ -248,7 +248,7 @@ void ProcessCommandExecutor::onProcessError() errorMessage = Tr::tr("Unknown process error running '%1'.").arg(binary); break; } - emit error(Error(errorMessage)); + emit error(ErrorInfo(errorMessage)); } void ProcessCommandExecutor::onProcessFinished(int exitCode) @@ -258,7 +258,7 @@ void ProcessCommandExecutor::onProcessFinished(int exitCode) sendProcessOutput(!errorOccurred); if (Q_UNLIKELY(errorOccurred)) { - emit error(Error(Tr::tr("Process failed with exit code %1.").arg(exitCode))); + emit error(ErrorInfo(Tr::tr("Process failed with exit code %1.").arg(exitCode))); return; } diff --git a/src/lib/buildgraph/productinstaller.cpp b/src/lib/buildgraph/productinstaller.cpp index 93ac80ffa..468f79f9d 100644 --- a/src/lib/buildgraph/productinstaller.cpp +++ b/src/lib/buildgraph/productinstaller.cpp @@ -56,16 +56,16 @@ ProductInstaller::ProductInstaller(const TopLevelProjectPtr &project, if (m_options.removeExistingInstallation()) { const QString cfp = installRootFileInfo.canonicalFilePath(); if (cfp == QFileInfo(QDir::rootPath()).canonicalFilePath()) - throw Error(Tr::tr("Refusing to remove root directory.")); + throw ErrorInfo(Tr::tr("Refusing to remove root directory.")); if (cfp == QFileInfo(QDir::homePath()).canonicalFilePath()) - throw Error(Tr::tr("Refusing to remove home directory.")); + throw ErrorInfo(Tr::tr("Refusing to remove home directory.")); } return; } if (m_options.installIntoSysroot()) { if (m_options.removeExistingInstallation()) - throw Error(Tr::tr("Refusing to remove sysroot.")); + throw ErrorInfo(Tr::tr("Refusing to remove sysroot.")); m_options.setInstallRoot(PropertyFinder().propertyValue(project->buildConfiguration(), QLatin1String("qbs"), QLatin1String("sysroot")).toString()); } else { @@ -116,7 +116,7 @@ void ProductInstaller::removeInstallRoot() void ProductInstaller::copyFile(const Artifact *artifact) { if (m_observer->canceled()) { - throw Error(Tr::tr("Installation canceled for configuration '%1'.") + throw ErrorInfo(Tr::tr("Installation canceled for configuration '%1'.") .arg(m_products.first()->project->topLevelProject()->id())); } const QString relativeInstallDir @@ -148,7 +148,7 @@ void ProductInstaller::copyFile(const Artifact *artifact) void ProductInstaller::handleError(const QString &message) { if (!m_options.keepGoing()) - throw Error(message); + throw ErrorInfo(message); m_logger.qbsWarning() << message; } diff --git a/src/lib/buildgraph/projectbuilddata.cpp b/src/lib/buildgraph/projectbuilddata.cpp index b885254ac..b81ada73f 100644 --- a/src/lib/buildgraph/projectbuilddata.cpp +++ b/src/lib/buildgraph/projectbuilddata.cpp @@ -288,7 +288,7 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc foreach (ResolvedProductPtr dependency, product->dependencies) { if (Q_UNLIKELY(!dependency->enabled)) { QString msg = Tr::tr("Product '%1' depends on '%2' but '%2' is disabled."); - throw Error(msg.arg(product->name, dependency->name)); + throw ErrorInfo(msg.arg(product->name, dependency->name)); } resolveProductBuildData(dependency); } @@ -322,7 +322,7 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc foreach (const QString &inputFileName, rtrafo->inputs) { Artifact *artifact = lookupArtifact(product, inputFileName); if (Q_UNLIKELY(!artifact)) - throw Error(QString("Can't find artifact '%0' in the list of source files.").arg(inputFileName)); + throw ErrorInfo(QString("Can't find artifact '%0' in the list of source files.").arg(inputFileName)); inputArtifacts += artifact; } TransformerPtr transformer = Transformer::create(); @@ -357,7 +357,7 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc transformer->setupOutputs(engine(), scope()); transformer->createCommands(rtrafo->transform, evalContext()); if (Q_UNLIKELY(transformer->commands.isEmpty())) - throw Error(QString("There's a transformer without commands."), rtrafo->transform->location); + throw ErrorInfo(QString("There's a transformer without commands."), rtrafo->transform->location); } RulesApplicator(product, artifactsPerFileTag, m_logger).applyAllRules(); diff --git a/src/lib/buildgraph/rulesapplicator.cpp b/src/lib/buildgraph/rulesapplicator.cpp index 11405a716..d51da8003 100644 --- a/src/lib/buildgraph/rulesapplicator.cpp +++ b/src/lib/buildgraph/rulesapplicator.cpp @@ -174,7 +174,7 @@ void RulesApplicator::doApply(const ArtifactList &inputArtifacts) scriptValue = engine()->evaluate(binding.code); if (Q_UNLIKELY(scriptValue.isError())) { QString msg = QLatin1String("evaluating rule binding '%1': %2"); - throw Error(msg.arg(binding.name.join(QLatin1String(".")), scriptValue.toString()), binding.location); + throw ErrorInfo(msg.arg(binding.name.join(QLatin1String(".")), scriptValue.toString()), binding.location); } setConfigProperty(artifactModulesCfg, binding.name, scriptValue.toVariant()); } @@ -186,7 +186,7 @@ void RulesApplicator::doApply(const ArtifactList &inputArtifacts) m_transformer->setupOutputs(engine(), scope()); m_transformer->createCommands(m_rule->script, evalContext()); if (Q_UNLIKELY(m_transformer->commands.isEmpty())) - throw Error(QString("There's a rule without commands: %1.").arg(m_rule->toString()), m_rule->script->location); + throw ErrorInfo(QString("There's a rule without commands: %1.").arg(m_rule->toString()), m_rule->script->location); } void RulesApplicator::setupScriptEngineForArtifact(Artifact *artifact) @@ -222,7 +222,7 @@ Artifact *RulesApplicator::createOutputArtifact(const RuleArtifactConstPtr &rule { QScriptValue scriptValue = engine()->evaluate(ruleArtifact->fileName); if (Q_UNLIKELY(scriptValue.isError() || engine()->hasUncaughtException())) - throw Error("Error in Rule.Artifact fileName: " + scriptValue.toString()); + throw ErrorInfo("Error in Rule.Artifact fileName: " + scriptValue.toString()); QString outputPath = scriptValue.toString(); outputPath.replace("..", "dotdot"); // don't let the output artifact "escape" its build dir outputPath = resolveOutPath(outputPath); @@ -256,7 +256,7 @@ Artifact *RulesApplicator::createOutputArtifact(const RuleArtifactConstPtr &rule .arg(outputArtifact->transformer->rule->script->location.line()) .arg(outputArtifact->transformer->rule->script->location.column()) .arg(th); - throw Error(e); + throw ErrorInfo(e); } } outputArtifact->fileTags += ruleArtifact->fileTags; diff --git a/src/lib/buildgraph/rulesevaluationcontext.cpp b/src/lib/buildgraph/rulesevaluationcontext.cpp index 28a58b4be..8ec7c7dad 100644 --- a/src/lib/buildgraph/rulesevaluationcontext.cpp +++ b/src/lib/buildgraph/rulesevaluationcontext.cpp @@ -72,7 +72,7 @@ void RulesEvaluationContext::incrementProgressValue() void RulesEvaluationContext::checkForCancelation() { if (Q_UNLIKELY(m_observer && m_observer->canceled())) - throw Error(Tr::tr("Build canceled.")); + throw ErrorInfo(Tr::tr("Build canceled.")); } void RulesEvaluationContext::initScope() diff --git a/src/lib/buildgraph/transformer.cpp b/src/lib/buildgraph/transformer.cpp index 4b2c777cf..edf4d4210 100644 --- a/src/lib/buildgraph/transformer.cpp +++ b/src/lib/buildgraph/transformer.cpp @@ -138,14 +138,14 @@ void Transformer::createCommands(const PrepareScriptConstPtr &script, if (!script->scriptFunction.isValid() || script->scriptFunction.engine() != engine) { script->scriptFunction = engine->evaluate(script->script); if (Q_UNLIKELY(!script->scriptFunction.isFunction())) - throw Error(Tr::tr("Invalid prepare script."), script->location); + throw ErrorInfo(Tr::tr("Invalid prepare script."), script->location); } engine->clearProperties(); QScriptValue scriptValue = script->scriptFunction.call(); modulePropertiesUsedInPrepareScript = engine->properties(); if (Q_UNLIKELY(engine->hasUncaughtException())) - throw Error("evaluating prepare script: " + engine->uncaughtException().toString(), + throw ErrorInfo("evaluating prepare script: " + engine->uncaughtException().toString(), CodeLocation(script->location.fileName(), script->location.line() + engine->uncaughtExceptionLineNumber() - 1)); diff --git a/src/lib/buildgraph/tst_buildgraph.cpp b/src/lib/buildgraph/tst_buildgraph.cpp index ff78860ec..235b11b43 100644 --- a/src/lib/buildgraph/tst_buildgraph.cpp +++ b/src/lib/buildgraph/tst_buildgraph.cpp @@ -59,7 +59,7 @@ bool TestBuildGraph::cycleDetected(const ResolvedProductConstPtr &product) try { CycleDetector(Logger(m_logSink)).visitProduct(product); return false; - } catch (const Error &) { + } catch (const ErrorInfo &) { return true; } } diff --git a/src/lib/language/evaluator.cpp b/src/lib/language/evaluator.cpp index e80351ca3..5dc870fd6 100644 --- a/src/lib/language/evaluator.cpp +++ b/src/lib/language/evaluator.cpp @@ -90,7 +90,7 @@ bool Evaluator::boolValue(const Item *item, const QString &name, bool defaultVal QScriptValue v = property(item, name); if (Q_UNLIKELY(v.isError())) { ValuePtr value = item->property(name); - throw Error(v.toString(), value ? value->location() : CodeLocation()); + throw ErrorInfo(v.toString(), value ? value->location() : CodeLocation()); } if (!v.isValid() || v.isUndefined()) { if (propertyWasSet) @@ -113,7 +113,7 @@ QString Evaluator::stringValue(const Item *item, const QString &name, QScriptValue v = property(item, name); if (Q_UNLIKELY(v.isError())) { ValuePtr value = item->property(name); - throw Error(v.toString(), value ? value->location() : CodeLocation()); + throw ErrorInfo(v.toString(), value ? value->location() : CodeLocation()); } if (!v.isValid() || v.isUndefined()) { if (propertyWasSet) @@ -130,7 +130,7 @@ QStringList Evaluator::stringListValue(const Item *item, const QString &name) QScriptValue v = property(item, name); if (Q_UNLIKELY(v.isError())) { ValuePtr value = item->property(name); - throw Error(v.toString(), value ? value->location() : CodeLocation()); + throw ErrorInfo(v.toString(), value ? value->location() : CodeLocation()); } return toStringList(v); } diff --git a/src/lib/language/importversion.cpp b/src/lib/language/importversion.cpp index 754359600..7590a9bd3 100644 --- a/src/lib/language/importversion.cpp +++ b/src/lib/language/importversion.cpp @@ -44,7 +44,7 @@ ImportVersion ImportVersion::fromString(const QString &str, const CodeLocation & { QStringList lst = str.split(QLatin1Char('.')); if (Q_UNLIKELY(lst.count() < 1 || lst.count() > 2)) - throw Error(Tr::tr("Wrong number of components in import version."), location); + throw ErrorInfo(Tr::tr("Wrong number of components in import version."), location); ImportVersion v; int *parts[] = {&v.m_major, &v.m_minor, 0}; for (int i = 0; i < lst.count(); ++i) { @@ -53,7 +53,7 @@ ImportVersion ImportVersion::fromString(const QString &str, const CodeLocation & bool ok; *parts[i] = lst.at(i).toInt(&ok); if (Q_UNLIKELY(!ok)) - throw Error(Tr::tr("Cannot parse import version."), location); + throw ErrorInfo(Tr::tr("Cannot parse import version."), location); } return v; } diff --git a/src/lib/language/item.h b/src/lib/language/item.h index d298c9788..2929006be 100644 --- a/src/lib/language/item.h +++ b/src/lib/language/item.h @@ -92,7 +92,7 @@ public: const PropertyDeclarationMap &propertyDeclarations() const; const Modules &modules() const; Modules &modules(); - const Error &error() const { return m_error; } + const ErrorInfo &error() const { return m_error; } bool hasProperty(const QString &name) const; bool hasOwnProperty(const QString &name) const; @@ -112,7 +112,7 @@ public: void setChildren(const QList<Item *> &children); void setParent(Item *item); static void addChild(Item *parent, Item *child); - void setError(const Error &error) { m_error = error; } + void setError(const ErrorInfo &error) { m_error = error; } private: ItemPool *m_pool; @@ -131,7 +131,7 @@ private: PropertyDeclarationMap m_propertyDeclarations; QList<FunctionDeclaration> m_functions; Modules m_modules; - Error m_error; // For SubProject items. May or may not be reported depending on their condition. + ErrorInfo m_error; // For SubProject items. May or may not be reported depending on their condition. }; inline ItemPool *Item::pool() const diff --git a/src/lib/language/itemreader.cpp b/src/lib/language/itemreader.cpp index ace12d92a..6222d6f1e 100644 --- a/src/lib/language/itemreader.cpp +++ b/src/lib/language/itemreader.cpp @@ -120,11 +120,11 @@ ItemReaderResult ItemReader::internalReadFile(const QString &filePath) ASTCacheValue &cacheValue = (*m_astCache)[filePath]; if (cacheValue.isValid()) { if (Q_UNLIKELY(cacheValue.isProcessing())) - throw Error(Tr::tr("Loop detected when importing '%1'.").arg(filePath)); + throw ErrorInfo(Tr::tr("Loop detected when importing '%1'.").arg(filePath)); } else { QFile file(filePath); if (Q_UNLIKELY(!file.open(QFile::ReadOnly))) - throw Error(Tr::tr("Couldn't open '%1'.").arg(filePath)); + throw ErrorInfo(Tr::tr("Couldn't open '%1'.").arg(filePath)); const QString code = QTextStream(&file).readAll(); QbsQmlJS::Lexer lexer(cacheValue.engine()); @@ -135,7 +135,7 @@ ItemReaderResult ItemReader::internalReadFile(const QString &filePath) if (!parser.parse()) { QList<QbsQmlJS::DiagnosticMessage> parserMessages = parser.diagnosticMessages(); if (Q_UNLIKELY(!parserMessages.isEmpty())) { - Error err; + ErrorInfo err; foreach (const QbsQmlJS::DiagnosticMessage &msg, parserMessages) err.append(msg.message, toCodeLocation(filePath, msg.loc)); throw err; diff --git a/src/lib/language/itemreaderastvisitor.cpp b/src/lib/language/itemreaderastvisitor.cpp index 4c73f749c..24bfb3936 100644 --- a/src/lib/language/itemreaderastvisitor.cpp +++ b/src/lib/language/itemreaderastvisitor.cpp @@ -69,7 +69,7 @@ bool ItemReaderASTVisitor::visit(AST::UiProgram *ast) m_file->m_filePath = m_filePath; if (Q_UNLIKELY(!ast->members->member)) - throw Error(Tr::tr("No root item found in %1.").arg(m_filePath)); + throw ErrorInfo(Tr::tr("No root item found in %1.").arg(m_filePath)); return true; } @@ -123,25 +123,25 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) if (isBase) checkImportVersion(import->versionToken); else if (import->versionToken.length) - m_reader->logger().printWarning(Error(Tr::tr("Superfluous version specification."), + m_reader->logger().printWarning(ErrorInfo(Tr::tr("Superfluous version specification."), toCodeLocation(import->versionToken))); } QString as; if (isBase) { if (Q_UNLIKELY(!import->importId.isNull())) { - throw Error(Tr::tr("Import of qbs.base must have no 'as <Name>'"), + throw ErrorInfo(Tr::tr("Import of qbs.base must have no 'as <Name>'"), toCodeLocation(import->importIdToken)); } } else { if (Q_UNLIKELY(import->importId.isNull())) { - throw Error(Tr::tr("Imports require 'as <Name>'"), + throw ErrorInfo(Tr::tr("Imports require 'as <Name>'"), toCodeLocation(import->importToken)); } as = import->importId.toString(); if (Q_UNLIKELY(importAsNames.contains(as))) { - throw Error(Tr::tr("Can't import into the same name more than once."), + throw ErrorInfo(Tr::tr("Can't import into the same name more than once."), toCodeLocation(import->importIdToken)); } importAsNames.insert(as); @@ -152,7 +152,7 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) QFileInfo fi(name); if (Q_UNLIKELY(!fi.exists())) - throw Error(Tr::tr("Can't find imported file %0.").arg(name), + throw ErrorInfo(Tr::tr("Can't find imported file %0.").arg(name), CodeLocation(m_filePath, import->fileNameToken.startLine, import->fileNameToken.startColumn)); name = fi.canonicalFilePath(); @@ -167,7 +167,7 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) } else if (name.endsWith(".qbs", Qt::CaseInsensitive)) { m_typeNameToFile.insert(QStringList(as), name); } else { - throw Error(Tr::tr("Can only import .qbs and .js files"), + throw ErrorInfo(Tr::tr("Can only import .qbs and .js files"), CodeLocation(m_filePath, import->fileNameToken.startLine, import->fileNameToken.startColumn)); } @@ -199,7 +199,7 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) } } if (Q_UNLIKELY(!found)) { - throw Error(Tr::tr("import %1 not found").arg(importUri.join(".")), + throw ErrorInfo(Tr::tr("import %1 not found").arg(importUri.join(".")), toCodeLocation(import->fileNameToken)); } } @@ -279,7 +279,7 @@ void ItemReaderASTVisitor::checkDuplicateBinding(Item *item, const QStringList & { if (Q_UNLIKELY(item->properties().contains(bindingName.last()))) { QString msg = Tr::tr("Duplicate binding for '%1'"); - throw Error(msg.arg(bindingName.join(".")), + throw ErrorInfo(msg.arg(bindingName.join(".")), qbs::Internal::toCodeLocation(m_file->filePath(), sourceLocation)); } } @@ -288,20 +288,20 @@ bool ItemReaderASTVisitor::visit(AST::UiPublicMember *ast) { PropertyDeclaration p; if (Q_UNLIKELY(ast->name.isEmpty())) - throw Error(Tr::tr("public member without name")); + throw ErrorInfo(Tr::tr("public member without name")); if (Q_UNLIKELY(ast->memberType.isEmpty())) - throw Error(Tr::tr("public member without type")); + throw ErrorInfo(Tr::tr("public member without type")); if (Q_UNLIKELY(ast->type == AST::UiPublicMember::Signal)) - throw Error(Tr::tr("public member with signal type not supported")); + throw ErrorInfo(Tr::tr("public member with signal type not supported")); p.name = ast->name.toString(); p.type = PropertyDeclaration::propertyTypeFromString(ast->memberType.toString()); if (p.type == PropertyDeclaration::UnknownType) - throw Error(Tr::tr("Unknown type '%1' in property declaration.") - .arg(ast->memberType.toString()), toCodeLocation(ast->typeToken)); + throw ErrorInfo(Tr::tr("Unknown type '%1' in property declaration.") + .arg(ast->memberType.toString()), toCodeLocation(ast->typeToken)); if (ast->typeModifier.compare(QLatin1String("list"))) p.flags |= PropertyDeclaration::ListProperty; else if (Q_UNLIKELY(!ast->typeModifier.isEmpty())) - throw Error(Tr::tr("public member with type modifier '%1' not supported").arg( + throw ErrorInfo(Tr::tr("public member with type modifier '%1' not supported").arg( ast->typeModifier.toString())); m_item->m_propertyDeclarations.insert(p.name, p); @@ -331,11 +331,11 @@ bool ItemReaderASTVisitor::visit(AST::UiScriptBinding *ast) AST::ExpressionStatement *expStmt = AST::cast<AST::ExpressionStatement *>(ast->statement); if (Q_UNLIKELY(!expStmt)) - throw Error(Tr::tr("id: must be followed by identifier")); + throw ErrorInfo(Tr::tr("id: must be followed by identifier")); AST::IdentifierExpression *idExp = AST::cast<AST::IdentifierExpression *>(expStmt->expression); if (Q_UNLIKELY(!idExp || idExp->name.isEmpty())) - throw Error(Tr::tr("id: must be followed by identifier")); + throw ErrorInfo(Tr::tr("id: must be followed by identifier")); m_item->m_id = idExp->name.toString(); ensureIdScope(m_file); m_file->m_idScope->m_properties[m_item->m_id] = ItemValue::create(m_item); @@ -358,7 +358,7 @@ bool ItemReaderASTVisitor::visit(AST::FunctionDeclaration *ast) { FunctionDeclaration f; if (Q_UNLIKELY(ast->name.isNull())) - throw Error(Tr::tr("function decl without name")); + throw ErrorInfo(Tr::tr("function decl without name")); f.setName(ast->name.toString()); // remove the name @@ -415,7 +415,7 @@ Item *ItemReaderASTVisitor::targetItemForBinding(Item *item, } if (Q_UNLIKELY(v->type() != Value::ItemValueType)) { QString msg = Tr::tr("Binding to non-item property."); - throw Error(msg, bindingLocation); + throw ErrorInfo(msg, bindingLocation); } ItemValuePtr jsv = v.staticCast<ItemValue>(); targetItem = jsv->item(); @@ -431,7 +431,7 @@ void ItemReaderASTVisitor::checkImportVersion(const AST::SourceLocation &version const ImportVersion importVersion = ImportVersion::fromString(importVersionString, toCodeLocation(versionToken)); if (Q_UNLIKELY(importVersion != m_languageVersion)) - throw Error(Tr::tr("Incompatible qbs version %1. This is qbs %2.").arg( + throw ErrorInfo(Tr::tr("Incompatible qbs version %1. This is qbs %2.").arg( importVersionString, m_reader->builtins()->languageVersion()), toCodeLocation(versionToken)); } @@ -559,7 +559,7 @@ private: } else if (it.value()->type() == Value::JSSourceValueType) { ValuePtr aval = a->property(it.key()); if (Q_UNLIKELY(aval && aval->type() != Value::JSSourceValueType)) - throw Error(Tr::tr("Incompatible value type in unconditional value at %1.").arg( + throw ErrorInfo(Tr::tr("Incompatible value type in unconditional value at %1.").arg( aval->location().toString())); apply(it.key(), a, aval.staticCast<JSSourceValue>(), it.value().staticCast<JSSourceValue>()); @@ -589,10 +589,10 @@ void ItemReaderASTVisitor::handlePropertiesBlock(Item *item, const Item *block) { ValuePtr value = block->property(QLatin1String("condition")); if (Q_UNLIKELY(!value)) - throw Error(Tr::tr("Properties.condition must be provided."), + throw ErrorInfo(Tr::tr("Properties.condition must be provided."), block->location()); if (Q_UNLIKELY(value->type() != Value::JSSourceValueType)) - throw Error(Tr::tr("Properties.condition must be a value binding."), + throw ErrorInfo(Tr::tr("Properties.condition must be a value binding."), block->location()); JSSourceValuePtr srcval = value.staticCast<JSSourceValue>(); const QString condition = srcval->sourceCode(); diff --git a/src/lib/language/language.cpp b/src/lib/language/language.cpp index 51586ef57..b95600b80 100644 --- a/src/lib/language/language.cpp +++ b/src/lib/language/language.cpp @@ -528,7 +528,7 @@ static QProcessEnvironment getProcessEnvironment(ScriptEngine *engine, EnvType e ctx->popScope(); if (Q_UNLIKELY(scriptValue.isError() || engine->hasUncaughtException())) { QString envTypeStr = (envType == BuildEnv ? "build" : "run"); - throw Error(QString("Error while setting up %1 environment: %2").arg(envTypeStr, scriptValue.toString())); + throw ErrorInfo(QString("Error while setting up %1 environment: %2").arg(envTypeStr, scriptValue.toString())); } } diff --git a/src/lib/language/moduleloader.cpp b/src/lib/language/moduleloader.cpp index 89f17b7d2..52ed8689a 100644 --- a/src/lib/language/moduleloader.cpp +++ b/src/lib/language/moduleloader.cpp @@ -162,7 +162,7 @@ void ModuleLoader::handleProject(ModuleLoaderResult *loadResult, Item *item) copyProperties(item, subItem); handleProject(loadResult, subItem); } else { - throw Error(Tr::tr("The top-level item of a file in a \"references\" list must be " + throw ErrorInfo(Tr::tr("The top-level item of a file in a \"references\" list must be " "a Product or a Project, but it is \"%1\".").arg(subItem->typeName()), subItem->location()); } @@ -245,7 +245,7 @@ void ModuleLoader::handleSubProject(ModuleLoader::ProjectContext *projectContext } if (loadedItem->typeName() != QLatin1String("Project")) { - Error error; + ErrorInfo error; error.append(Tr::tr("Expected Project item, but encountered '%1'.") .arg(loadedItem->typeName()), loadedItem->location()); const ValuePtr &filePathProperty = item->properties().value(QLatin1String("filePath")); @@ -321,7 +321,7 @@ void ModuleLoader::deferExportItem(ModuleLoader::ProductContext *productContext, void ModuleLoader::handleProductModule(ModuleLoader::ProductContext *productContext, Item *item) { - m_logger.printWarning(Error(Tr::tr("ProductModule {} is deprecated. " + m_logger.printWarning(ErrorInfo(Tr::tr("ProductModule {} is deprecated. " "Please use Export {} instead."), item->location())); deferExportItem(productContext, item); } @@ -349,7 +349,7 @@ void ModuleLoader::mergeExportItems(ModuleLoader::ProductContext *productContext foreach (Item *exportItem, productContext->exportItems) { checkCancelation(); if (Q_UNLIKELY(productContext->filesWithExportItem.contains(exportItem->file()))) - throw Error(Tr::tr("Multiple Export items in one product are prohibited."), + throw ErrorInfo(Tr::tr("Multiple Export items in one product are prohibited."), exportItem->location()); merged->setLocation(exportItem->location()); productContext->filesWithExportItem += exportItem->file(); @@ -422,7 +422,7 @@ void ModuleLoader::resolveDependencies(DependsContext *dependsContext, Item *ite foreach (const Item::Module &module, it.value()) { const QString fullName = fullModuleName(module.name); if (loadedModuleNames.contains(fullName)) { - m_logger.printWarning(Error(Tr::tr("Duplicate dependency '%1'.").arg(fullName), + m_logger.printWarning(ErrorInfo(Tr::tr("Duplicate dependency '%1'.").arg(fullName), item->location())); continue; } @@ -451,21 +451,21 @@ void ModuleLoader::resolveDependsItem(DependsContext *dependsContext, Item *item const QStringList nameParts = name.split('.'); if (Q_UNLIKELY(nameParts.count() > 2)) { QString msg = Tr::tr("There cannot be more than one dot in a module name."); - throw Error(msg, dependsItem->location()); + throw ErrorInfo(msg, dependsItem->location()); } QString superModuleName; QStringList submodules = toStringList(m_evaluator->property(dependsItem, "submodules")); if (nameParts.count() == 2) { if (Q_UNLIKELY(!submodules.isEmpty())) - throw Error(Tr::tr("Depends.submodules cannot be used if name contains a dot."), + throw ErrorInfo(Tr::tr("Depends.submodules cannot be used if name contains a dot."), dependsItem->location()); superModuleName = nameParts.first(); submodules += nameParts.last(); } if (Q_UNLIKELY(submodules.count() > 1 && !dependsItem->id().isEmpty())) { QString msg = Tr::tr("A Depends item with more than one module cannot have an id."); - throw Error(msg, dependsItem->location()); + throw ErrorInfo(msg, dependsItem->location()); } if (superModuleName.isEmpty()) { if (submodules.isEmpty()) @@ -578,7 +578,7 @@ Item *ModuleLoader::searchAndLoadModuleFile(ProductContext *productContext, } if (Q_UNLIKELY(triedToLoadModule)) - throw Error(Tr::tr("Module %1 could not be loaded.").arg(fullModuleName(moduleName)), + throw ErrorInfo(Tr::tr("Module %1 could not be loaded.").arg(fullModuleName(moduleName)), dependsItemLocation); return 0; @@ -626,7 +626,7 @@ void ModuleLoader::loadBaseModule(ProductContext *productContext, Item *item) baseModuleDesc.item = loadModule(productContext, item, CodeLocation(), QString(), baseModuleName); if (Q_UNLIKELY(!baseModuleDesc.item)) - throw Error(Tr::tr("Cannot load base qbs module.")); + throw ErrorInfo(Tr::tr("Cannot load base qbs module.")); baseModuleDesc.item->setProperty(QLatin1String("getenv"), BuiltinValue::create(BuiltinValue::GetEnvFunction)); baseModuleDesc.item->setProperty(QLatin1String("getHostOS"), @@ -687,8 +687,8 @@ static QVariant convertToPropertyType(const QVariant &v, PropertyDeclaration::Ty if (!c.convert(vt)) { QStringList name = namePrefix; name << key; - throw Error(Tr::tr("Value '%1' of property '%2' has incompatible type.").arg(v.toString()) - .arg(name.join(QLatin1String(".")))); + throw ErrorInfo(Tr::tr("Value '%1' of property '%2' has incompatible type.") + .arg(v.toString(), name.join(QLatin1String(".")))); } return c; } @@ -769,10 +769,11 @@ void ModuleLoader::instantiateModule(ProductContext *productContext, Item *insta // override module properties given on the command line const QVariantMap userModuleProperties = m_userProperties.value(fullName).toMap(); for (QVariantMap::const_iterator vmit = userModuleProperties.begin(); - vmit != userModuleProperties.end(); ++vmit) - { - if (Q_UNLIKELY(!moduleInstance->hasProperty(vmit.key()))) - throw Error(Tr::tr("Unknown property: %1.%2").arg(fullModuleName(moduleName), vmit.key())); + vmit != userModuleProperties.end(); ++vmit) { + if (Q_UNLIKELY(!moduleInstance->hasProperty(vmit.key()))) { + throw ErrorInfo(Tr::tr("Unknown property: %1.%2") + .arg(fullModuleName(moduleName), vmit.key())); + } const PropertyDeclaration decl = firstValidPropertyDeclaration(moduleInstance, vmit.key()); moduleInstance->setProperty(vmit.key(), VariantValue::create(convertToPropertyType(vmit.value(), decl.type, moduleName, @@ -808,7 +809,7 @@ void ModuleLoader::resolveProbe(Item *parent, Item *probe) { const JSSourceValueConstPtr configureScript = probe->sourceProperty(QLatin1String("configure")); if (Q_UNLIKELY(!configureScript)) - throw Error(Tr::tr("Probe.configure must be set."), probe->location()); + throw ErrorInfo(Tr::tr("Probe.configure must be set."), probe->location()); typedef QPair<QString, QScriptValue> ProbeProperty; QList<ProbeProperty> probeBindings; for (Item *obj = probe; obj; obj = obj->prototype()) { @@ -818,7 +819,7 @@ void ModuleLoader::resolveProbe(Item *parent, Item *probe) QScriptValue sv = m_evaluator->property(probe, name); if (Q_UNLIKELY(sv.isError())) { ValuePtr value = obj->property(name); - throw Error(sv.toString(), value ? value->location() : CodeLocation()); + throw ErrorInfo(sv.toString(), value ? value->location() : CodeLocation()); } probeBindings += ProbeProperty(name, sv); } @@ -834,7 +835,7 @@ void ModuleLoader::resolveProbe(Item *parent, Item *probe) scope.setProperty(b.first, b.second); QScriptValue sv = m_engine->evaluate(configureScript->sourceCode()); if (Q_UNLIKELY(sv.isError())) - throw Error(sv.toString(), configureScript->location()); + throw ErrorInfo(sv.toString(), configureScript->location()); foreach (const ProbeProperty &b, probeBindings) { const QVariant newValue = scope.property(b.first).toVariant(); if (newValue != b.second.toVariant()) @@ -848,7 +849,7 @@ void ModuleLoader::resolveProbe(Item *parent, Item *probe) void ModuleLoader::checkCancelation() const { if (m_progressObserver && m_progressObserver->canceled()) { - throw Error(Tr::tr("Project resolving canceled for configuration %1.") + throw ErrorInfo(Tr::tr("Project resolving canceled for configuration %1.") .arg(TopLevelProject::deriveId(m_userProperties))); } } diff --git a/src/lib/language/projectresolver.cpp b/src/lib/language/projectresolver.cpp index a9b5a14b3..a30260add 100644 --- a/src/lib/language/projectresolver.cpp +++ b/src/lib/language/projectresolver.cpp @@ -101,7 +101,7 @@ TopLevelProjectPtr ProjectResolver::resolve(ModuleLoaderResult &loadResult, void ProjectResolver::checkCancelation() const { if (m_progressObserver && m_progressObserver->canceled()) { - throw Error(Tr::tr("Project resolving canceled for configuration %1.") + throw ErrorInfo(Tr::tr("Project resolving canceled for configuration %1.") .arg(TopLevelProject::deriveId(m_buildConfiguration))); } } @@ -218,8 +218,24 @@ void ProjectResolver::resolveSubProject(Item *item, ProjectResolver::ProjectCont ProjectContext subProjectContext = createProjectContext(projectContext); foreach (Item * const subItem, item->children()) { - if (subItem->typeName() == QLatin1String("Project")) + if (subItem->typeName() == QLatin1String("Project")) { resolveProject(subItem, &subProjectContext); + return; + } + } + + // No project item was found, which means the project was disabled. + subProjectContext.project->enabled = false; + Item *propertiesItem = 0; + foreach (Item * const subItem, item->children()) { + if (subItem->typeName() == QLatin1String("Properties")) { + propertiesItem = subItem; + break; + } + } + if (propertiesItem) { + subProjectContext.project->name + = m_evaluator->stringValue(propertiesItem, QLatin1String("name")); } } @@ -379,7 +395,7 @@ void ProjectResolver::resolveGroup(Item *item, ProjectContext *projectContext) = m_evaluator->stringListValue(item, QLatin1String("fileTagsFilter")); if (!fileTagsFilter.isEmpty()) { if (Q_UNLIKELY(!files.isEmpty())) - throw Error(Tr::tr("Group.files and Group.fileTagsFilters are exclusive."), + throw ErrorInfo(Tr::tr("Group.files and Group.fileTagsFilters are exclusive."), item->location()); ArtifactPropertiesPtr aprops = ArtifactProperties::create(); aprops->setFileTagsFilter(FileTags::fromStringList(fileTagsFilter)); @@ -392,7 +408,7 @@ void ProjectResolver::resolveGroup(Item *item, ProjectContext *projectContext) if (Q_UNLIKELY(files.isEmpty() && !item->hasProperty(QLatin1String("files")))) { // Yield an error if Group without files binding is encountered. // An empty files value is OK but a binding must exist. - throw Error(Tr::tr("Group without files is not allowed."), + throw ErrorInfo(Tr::tr("Group without files is not allowed."), item->location()); } QStringList patterns; @@ -428,15 +444,15 @@ void ProjectResolver::resolveGroup(Item *item, ProjectContext *projectContext) foreach (const QString &fileName, files) createSourceArtifact(m_productContext->product, properties, fileName, fileTags, overrideTags, group->files); - Error fileError; + ErrorInfo fileError; foreach (const SourceArtifactConstPtr &a, group->files) { if (!FileInfo(a->absoluteFilePath).exists()) { fileError.append(Tr::tr("File '%1' does not exist.") .arg(a->absoluteFilePath), item->property("files")->location()); } } - if (!fileError.entries().isEmpty()) - throw Error(fileError); + if (fileError.hasError()) + throw ErrorInfo(fileError); group->name = m_evaluator->stringValue(item, "name"); if (group->name.isEmpty()) @@ -470,14 +486,14 @@ void ProjectResolver::resolveRule(Item *item, ProjectContext *projectContext) bool hasAlwaysUpdatedArtifact = false; foreach (Item *child, item->children()) { if (Q_UNLIKELY(child->typeName() != QLatin1String("Artifact"))) - throw Error(Tr::tr("'Rule' can only have children of type 'Artifact'."), + throw ErrorInfo(Tr::tr("'Rule' can only have children of type 'Artifact'."), child->location()); resolveRuleArtifact(rule, child, &hasAlwaysUpdatedArtifact); } if (Q_UNLIKELY(!hasAlwaysUpdatedArtifact)) - throw Error(Tr::tr("At least one output artifact of a rule " + throw ErrorInfo(Tr::tr("At least one output artifact of a rule " "must have alwaysUpdated set to true."), item->location()); @@ -608,12 +624,12 @@ void ProjectResolver::resolveTransformer(Item *item, ProjectContext *projectCont foreach (const Item *child, item->children()) { if (Q_UNLIKELY(child->typeName() != QLatin1String("Artifact"))) - throw Error(Tr::tr("Transformer: wrong child type '%0'.").arg(child->typeName())); + throw ErrorInfo(Tr::tr("Transformer: wrong child type '%0'.").arg(child->typeName())); SourceArtifactPtr artifact = SourceArtifact::create(); artifact->properties = m_productContext->product->properties; QString fileName = m_evaluator->stringValue(child, "fileName"); if (Q_UNLIKELY(fileName.isEmpty())) - throw Error(Tr::tr("Artifact fileName must not be empty.")); + throw ErrorInfo(Tr::tr("Artifact fileName must not be empty.")); artifact->absoluteFilePath = FileInfo::resolvePath(m_productContext->product->topLevelProject()->buildDirectory, fileName); artifact->fileTags = m_evaluator->fileTagsValue(child, "fileTags"); @@ -678,7 +694,7 @@ void ProjectResolver::resolveProductDependencies(ProjectContext *projectContext) ResolvedProductPtr usedProduct = m_productsByName.value(dependency.name); if (Q_UNLIKELY(!usedProduct)) - throw Error(Tr::tr("Product dependency '%1' not found.").arg(dependency.name), + throw ErrorInfo(Tr::tr("Product dependency '%1' not found.").arg(dependency.name), productItem->location()); Item *usedProductItem = m_productItemMap.value(usedProduct); const ModuleLoaderResult::ProductInfo usedProductInfo @@ -699,7 +715,7 @@ void ProjectResolver::resolveProductDependencies(ProjectContext *projectContext) const QString &usedProductName = dependency.name; ResolvedProductPtr usedProduct = m_productsByName.value(usedProductName); if (Q_UNLIKELY(!usedProduct)) - throw Error(Tr::tr("Product dependency '%1' not found.").arg(usedProductName), + throw ErrorInfo(Tr::tr("Product dependency '%1' not found.").arg(usedProductName), productItem->location()); rproduct->dependencies.insert(usedProduct); @@ -812,7 +828,7 @@ QVariantMap ProjectResolver::evaluateProperties(Item *item, } const QScriptValue scriptValue = m_evaluator->property(item, it.key()); if (Q_UNLIKELY(scriptValue.isError())) - throw Error(scriptValue.toString(), it.value()->location()); + throw ErrorInfo(scriptValue.toString(), it.value()->location()); QVariant v = scriptValue.toVariant(); if (pd.type == PropertyDeclaration::Path) v = convertPathProperty(v.toString(), @@ -869,7 +885,7 @@ void ProjectResolver::callItemFunction(const ItemFuncMap &mappings, Item *item, ItemFuncPtr f = mappings.value(typeName); if (Q_UNLIKELY(!f)) { const QString msg = Tr::tr("Unexpected item type '%1'."); - throw Error(msg.arg(item->typeName()), item->location()); + throw ErrorInfo(msg.arg(item->typeName()), item->location()); } if (typeName == "Project") { ProjectContext subProjectContext = createProjectContext(projectContext); diff --git a/src/lib/language/scriptengine.cpp b/src/lib/language/scriptengine.cpp index 3699c96a7..800d35435 100644 --- a/src/lib/language/scriptengine.cpp +++ b/src/lib/language/scriptengine.cpp @@ -92,7 +92,7 @@ void ScriptEngine::import(const JsImport &jsImport, QScriptValue scope, QScriptV m_logger.qbsDebug() << "[ENGINE] " << fileName << " (cache miss)"; QFile file(fileName); if (Q_UNLIKELY(!file.open(QFile::ReadOnly))) - throw Error(tr("Cannot open '%1'.").arg(fileName)); + throw ErrorInfo(tr("Cannot open '%1'.").arg(fileName)); const QString sourceCode = QTextStream(&file).readAll(); file.close(); QScriptProgram program(sourceCode, fileName); @@ -193,7 +193,7 @@ void ScriptEngine::importProgram(const QScriptProgram &program, const QScriptVal currentContext()->popScope(); popContext(); if (Q_UNLIKELY(result.isError())) - throw Error(tr("Error when importing '%1': %2").arg(program.fileName(), result.toString())); + throw ErrorInfo(tr("Error when importing '%1': %2").arg(program.fileName(), result.toString())); // If targetObject is already an object, it doesn't get overwritten but enhanced by the // contents of the .js file. diff --git a/src/lib/language/tst_language.cpp b/src/lib/language/tst_language.cpp index 9e6157b0a..b5fa2aae2 100644 --- a/src/lib/language/tst_language.cpp +++ b/src/lib/language/tst_language.cpp @@ -100,7 +100,7 @@ void TestLanguage::handleInitCleanupDataTags(const char *projectFileName, bool * defaultParameters.setProjectFilePath(testProject(projectFileName)); project = loader->loadProject(defaultParameters); QVERIFY(project); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -162,7 +162,7 @@ void TestLanguage::baseProperty() QVariantMap cfg = product->properties->value(); QCOMPARE(cfg.value("narf").toStringList(), QStringList() << "boo"); QCOMPARE(cfg.value("zort").toStringList(), QStringList() << "bar" << "boo"); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -238,7 +238,7 @@ void TestLanguage::conditionalDepends() QVERIFY(product); dependency = findModuleByName(product, "doesonlyexistifhellfreezesover"); QVERIFY(!dependency); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -267,7 +267,7 @@ void TestLanguage::environmentVariable() QHash<QString, ResolvedProductPtr> products = productsFromProject(project); ResolvedProductPtr product = products.value(productName); QVERIFY(product); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -300,7 +300,7 @@ void TestLanguage::erroneousFiles() try { defaultParameters.setProjectFilePath(testProject("/erroneous/") + fileName); loader->loadProject(defaultParameters); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { if (!e.toString().contains(errorMessage)) { qDebug() << "Message: " << e.toString(); qDebug() << "Expected: " << errorMessage; @@ -360,7 +360,7 @@ void TestLanguage::exports() propertyValue = getConfigProperty(product->properties->value(), propertyName); QCOMPARE(propertyValue.toStringList(), QStringList() << "ABC"); } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -381,7 +381,7 @@ void TestLanguage::fileContextProperties() QCOMPARE(cfg.value("narf").toString(), defaultParameters.projectFilePath()); QString dirPath = QFileInfo(defaultParameters.projectFilePath()).absolutePath(); QCOMPARE(cfg.value("zort").toString(), dirPath); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -461,7 +461,7 @@ void TestLanguage::groupName() QVERIFY(group); QCOMPARE(group->name, QString("Group 2")); } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -497,7 +497,7 @@ void TestLanguage::homeDirectory() QCOMPARE(product->properties->value().value("user").toString(), FileInfo::resolvePath(product->sourceDirectory, QLatin1String("~foo/bar"))); } - catch (const Error &e) { + catch (const ErrorInfo &e) { qDebug() << e.toString(); } } @@ -585,7 +585,7 @@ void TestLanguage::idUsage() QVERIFY(products.contains("product2_2")); QVERIFY(products.contains("product3_3")); } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -695,7 +695,7 @@ void TestLanguage::jsImportUsedInMultipleScopes() QVERIFY(product); QCOMPARE(product->name, expectedProductName); } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -772,7 +772,7 @@ void TestLanguage::moduleScope() QCOMPARE(ipf.intValue("g"), 156); // overridden, dependent on product properties QCOMPARE(ipf.intValue("h"), 158); // overridden, base dependent on product properties } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -850,7 +850,7 @@ void TestLanguage::outerInGroup() installDir = artifact->properties->qbsPropertyValue("installDir"); QCOMPARE(installDir.toString(), QString("/somewhere/else")); } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -881,7 +881,7 @@ void TestLanguage::pathProperties() FileInfo::resolvePath(projectFileDir, QLatin1String("foo"))); QCOMPARE(cfg.value("base_fileInBaseProductDir").toString(), FileInfo::resolvePath(projectFileDir, QLatin1String("subdir/bar"))); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -914,7 +914,7 @@ void TestLanguage::productConditions() QVERIFY(product); QVERIFY(!product->enabled); } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -938,7 +938,7 @@ void TestLanguage::productDirectories() buildDir(defaultParameters)); QCOMPARE(config.value(QLatin1String("sourceDirectory")).toString(), testDataDir()); } - catch (const Error &e) { + catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } @@ -1266,7 +1266,7 @@ void TestLanguage::wildcards() actualFilePaths.sort(); expected.sort(); QCOMPARE(actualFilePaths, expected); - } catch (const Error &e) { + } catch (const ErrorInfo &e) { exceptionCaught = true; qDebug() << e.toString(); } diff --git a/src/lib/logging/ilogsink.cpp b/src/lib/logging/ilogsink.cpp index 29b2ce7c2..fd7d44405 100644 --- a/src/lib/logging/ilogsink.cpp +++ b/src/lib/logging/ilogsink.cpp @@ -91,7 +91,7 @@ LoggerLevel ILogSink::logLevel() const return d->logLevel; } -void ILogSink::printWarning(const Error &warning) +void ILogSink::printWarning(const ErrorInfo &warning) { if (willPrint(LoggerWarning)) { d->mutex.lock(); @@ -110,7 +110,7 @@ void ILogSink::printMessage(LoggerLevel level, const QString &message, const QSt } } -void ILogSink::doPrintWarning(const Error &warning) +void ILogSink::doPrintWarning(const ErrorInfo &warning) { doPrintMessage(LoggerWarning, warning.toString(), QString()); } diff --git a/src/lib/logging/ilogsink.h b/src/lib/logging/ilogsink.h index 541e71e64..ab8a40cc7 100644 --- a/src/lib/logging/ilogsink.h +++ b/src/lib/logging/ilogsink.h @@ -34,7 +34,7 @@ #include <QString> namespace qbs { -class Error; +class ErrorInfo; enum LoggerLevel { @@ -63,12 +63,12 @@ public: bool willPrint(LoggerLevel level) const { return level <= logLevel(); } - void printWarning(const Error &warning); + void printWarning(const ErrorInfo &warning); void printMessage(LoggerLevel level, const QString &message, const QString &tag = QString(), bool force = false); private: - virtual void doPrintWarning(const Error &warning); + virtual void doPrintWarning(const ErrorInfo &warning); virtual void doPrintMessage(LoggerLevel level, const QString &message, const QString &tag) = 0; diff --git a/src/lib/logging/logger.h b/src/lib/logging/logger.h index 8af0e2664..871b5f14e 100644 --- a/src/lib/logging/logger.h +++ b/src/lib/logging/logger.h @@ -104,7 +104,7 @@ public: bool debugEnabled() const; bool traceEnabled() const; - void printWarning(const Error &warning) { logSink()->printWarning(warning); } + void printWarning(const ErrorInfo &warning) { logSink()->printWarning(warning); } LogWriter qbsLog(LoggerLevel level, bool force = false) const; LogWriter qbsWarning() const { return qbsLog(LoggerWarning); } diff --git a/src/lib/tools/error.cpp b/src/lib/tools/error.cpp index 279b74b3d..c2a80023c 100644 --- a/src/lib/tools/error.cpp +++ b/src/lib/tools/error.cpp @@ -34,7 +34,7 @@ namespace qbs { -class ErrorData::ErrorDataPrivate : public QSharedData +class ErrorItem::ErrorItemPrivate : public QSharedData { public: QString description; @@ -48,37 +48,37 @@ public: * \sa Error */ -ErrorData::ErrorData() : d(new ErrorDataPrivate) +ErrorItem::ErrorItem() : d(new ErrorItemPrivate) { } -ErrorData::ErrorData(const QString &description, const CodeLocation &codeLocation) - : d(new ErrorDataPrivate) +ErrorItem::ErrorItem(const QString &description, const CodeLocation &codeLocation) + : d(new ErrorItemPrivate) { d->description = description; d->codeLocation = codeLocation; } -ErrorData::ErrorData(const ErrorData &rhs) : d(rhs.d) +ErrorItem::ErrorItem(const ErrorItem &rhs) : d(rhs.d) { } -ErrorData &ErrorData::operator=(const ErrorData &other) +ErrorItem &ErrorItem::operator=(const ErrorItem &other) { d = other.d; return *this; } -ErrorData::~ErrorData() +ErrorItem::~ErrorItem() { } -QString ErrorData::description() const +QString ErrorItem::description() const { return d->description; } -CodeLocation ErrorData::codeLocation() const +CodeLocation ErrorItem::codeLocation() const { return d->codeLocation; } @@ -97,7 +97,7 @@ CodeLocation ErrorData::codeLocation() const /*! * \brief A full textual description of the error using all available information. */ -QString ErrorData::toString() const +QString ErrorItem::toString() const { QString str = codeLocation().toString(); if (!str.isEmpty()) @@ -106,10 +106,10 @@ QString ErrorData::toString() const } -class Error::ErrorPrivate : public QSharedData +class ErrorInfo::ErrorInfoPrivate : public QSharedData { public: - QList<ErrorData> items; + QList<ErrorItem> items; }; /*! @@ -119,37 +119,37 @@ public: * \sa ErrorData */ -Error::Error() : d(new ErrorPrivate) +ErrorInfo::ErrorInfo() : d(new ErrorInfoPrivate) { } -Error::Error(const Error &rhs) : d(rhs.d) +ErrorInfo::ErrorInfo(const ErrorInfo &rhs) : d(rhs.d) { } -Error::Error(const QString &description, const CodeLocation &location) : d(new ErrorPrivate) +ErrorInfo::ErrorInfo(const QString &description, const CodeLocation &location) : d(new ErrorInfoPrivate) { append(description, location); } -Error &Error::operator =(const Error &other) +ErrorInfo &ErrorInfo::operator =(const ErrorInfo &other) { d = other.d; return *this; } -Error::~Error() +ErrorInfo::~ErrorInfo() { } -void Error::append(const QString &description, const CodeLocation &location) +void ErrorInfo::append(const QString &description, const CodeLocation &location) { - d->items.append(ErrorData(description, location)); + d->items.append(ErrorItem(description, location)); } -void Error::prepend(const QString &description, const CodeLocation &location) +void ErrorInfo::prepend(const QString &description, const CodeLocation &location) { - d->items.prepend(ErrorData(description, location)); + d->items.prepend(ErrorItem(description, location)); } /*! @@ -157,12 +157,12 @@ void Error::prepend(const QString &description, const CodeLocation &location) * Most often, there will be one element in this list, but there can be more e.g. to illustrate * how an error condition propagates through several source files. */ -QList<ErrorData> Error::entries() const +QList<ErrorItem> ErrorInfo::items() const { return d->items; } -void Error::clear() +void ErrorInfo::clear() { d->items.clear(); } @@ -172,10 +172,10 @@ void Error::clear() * All "sub-errors" will be represented. * \sa Error::entries() */ -QString Error::toString() const +QString ErrorInfo::toString() const { QStringList lines; - foreach (const ErrorData &e, d->items) + foreach (const ErrorItem &e, d->items) lines.append(e.toString()); return lines.join(QLatin1String("\n")); } diff --git a/src/lib/tools/error.h b/src/lib/tools/error.h index ef0515e22..9b40d0560 100644 --- a/src/lib/tools/error.h +++ b/src/lib/tools/error.h @@ -44,46 +44,49 @@ QT_END_NAMESPACE namespace qbs { class CodeLocation; -class QBS_EXPORT ErrorData +class QBS_EXPORT ErrorItem { + friend class ErrorInfo; public: - ErrorData(); - ErrorData(const QString &description, const CodeLocation &codeLocation); - ErrorData(const ErrorData &rhs); - ErrorData &operator=(const ErrorData &other); - ~ErrorData(); + ErrorItem(); + ErrorItem(const ErrorItem &rhs); + ErrorItem &operator=(const ErrorItem &other); + ~ErrorItem(); QString description() const; CodeLocation codeLocation() const; QString toString() const; private: - class ErrorDataPrivate; - QExplicitlySharedDataPointer<ErrorDataPrivate> d; + ErrorItem(const QString &description, const CodeLocation &codeLocation); + + class ErrorItemPrivate; + QExplicitlySharedDataPointer<ErrorItemPrivate> d; }; -class QBS_EXPORT Error +class QBS_EXPORT ErrorInfo { public: - Error(); - Error(const Error &rhs); - Error(const QString &description, const CodeLocation &location = CodeLocation()); - Error &operator=(const Error &other); - ~Error(); + ErrorInfo(); + ErrorInfo(const ErrorInfo &rhs); + ErrorInfo(const QString &description, const CodeLocation &location = CodeLocation()); + ErrorInfo &operator=(const ErrorInfo &other); + ~ErrorInfo(); void append(const QString &description, const CodeLocation &location = CodeLocation()); void prepend(const QString &description, const CodeLocation &location = CodeLocation()); - QList<ErrorData> entries() const; + QList<ErrorItem> items() const; + bool hasError() const { return !items().isEmpty(); } void clear(); QString toString() const; private: - class ErrorPrivate; - QSharedDataPointer<ErrorPrivate> d; + class ErrorInfoPrivate; + QSharedDataPointer<ErrorInfoPrivate> d; }; } // namespace qbs -Q_DECLARE_METATYPE(qbs::Error) +Q_DECLARE_METATYPE(qbs::ErrorInfo) #endif // QBS_ERROR diff --git a/src/lib/tools/persistence.cpp b/src/lib/tools/persistence.cpp index 6a633d09b..96de019b1 100644 --- a/src/lib/tools/persistence.cpp +++ b/src/lib/tools/persistence.cpp @@ -56,9 +56,9 @@ void PersistentPool::load(const QString &filePath) { QScopedPointer<QFile> file(new QFile(filePath)); if (!file->exists()) - throw Error(Tr::tr("No build graph exists yet for this configuration.")); + throw ErrorInfo(Tr::tr("No build graph exists yet for this configuration.")); if (!file->open(QFile::ReadOnly)) { - throw Error(Tr::tr("Could not open open build graph file '%1': %2") + throw ErrorInfo(Tr::tr("Could not open open build graph file '%1': %2") .arg(filePath, file->errorString())); } @@ -69,7 +69,7 @@ void PersistentPool::load(const QString &filePath) file->close(); file->remove(); m_stream.setDevice(0); - throw Error(Tr::tr("Cannot use stored build graph at '%1': Incompatible file format. " + throw ErrorInfo(Tr::tr("Cannot use stored build graph at '%1': Incompatible file format. " "Expected magic token '%2', got '%3'.") .arg(filePath, QString::fromLatin1(QBS_PERSISTENCE_MAGIC), QString::fromLatin1(magic))); diff --git a/src/lib/tools/profile.cpp b/src/lib/tools/profile.cpp index 67a66d1ee..50a0307db 100644 --- a/src/lib/tools/profile.cpp +++ b/src/lib/tools/profile.cpp @@ -164,7 +164,7 @@ QString Profile::baseProfileKey() void Profile::checkBaseProfileExistence(const Profile &baseProfile) const { if (!baseProfile.exists()) - throw Error(Internal::Tr::tr("Profile \"%1\" has a non-existent base profile \"%2\".").arg( + throw ErrorInfo(Internal::Tr::tr("Profile \"%1\" has a non-existent base profile \"%2\".").arg( name(), baseProfile.name())); } @@ -216,7 +216,7 @@ void Profile::extendAndCheckProfileChain(QStringList &chain) const { chain << m_name; if (Q_UNLIKELY(chain.count(m_name) > 1)) { - throw Error(Internal::Tr::tr("Circular profile inheritance. Cycle is '%1'.") + throw ErrorInfo(Internal::Tr::tr("Circular profile inheritance. Cycle is '%1'.") .arg(chain.join(QLatin1String(" -> ")))); } } diff --git a/src/lib/tools/qbsassert.cpp b/src/lib/tools/qbsassert.cpp index d9e1f78d7..484b8057c 100644 --- a/src/lib/tools/qbsassert.cpp +++ b/src/lib/tools/qbsassert.cpp @@ -42,7 +42,7 @@ void writeAssertLocation(const char *condition, const char *file, int line) void throwAssertLocation(const char *condition, const char *file, int line) { - throw Error(QString(QLatin1String("ASSERT: %1")).arg(condition), + throw ErrorInfo(QString(QLatin1String("ASSERT: %1")).arg(condition), CodeLocation(QString::fromLocal8Bit(file), line)); } diff --git a/src/lib/tools/settings.cpp b/src/lib/tools/settings.cpp index 924a6ceff..94d6ef826 100644 --- a/src/lib/tools/settings.cpp +++ b/src/lib/tools/settings.cpp @@ -139,9 +139,9 @@ void Settings::checkStatus() case QSettings::NoError: break; case QSettings::AccessError: - throw Error(Tr::tr("%1 is not accessible.").arg(m_settings->fileName())); + throw ErrorInfo(Tr::tr("%1 is not accessible.").arg(m_settings->fileName())); case QSettings::FormatError: - throw Error(Tr::tr("Format error in %1.").arg(m_settings->fileName())); + throw ErrorInfo(Tr::tr("Format error in %1.").arg(m_settings->fileName())); } } diff --git a/src/lib/tools/setupprojectparameters.cpp b/src/lib/tools/setupprojectparameters.cpp index 83ef55902..a0d8df6c8 100644 --- a/src/lib/tools/setupprojectparameters.cpp +++ b/src/lib/tools/setupprojectparameters.cpp @@ -221,16 +221,16 @@ QVariantMap SetupProjectParameters::buildConfigurationTree() const * This method returns an Error. The list of entries in this error will be empty is the * expansion was successful. */ -Error SetupProjectParameters::expandBuildConfiguration(Settings *settings) +ErrorInfo SetupProjectParameters::expandBuildConfiguration(Settings *settings) { - Error err; + ErrorInfo err; // Generates a full build configuration from user input, using the settings. QVariantMap expandedConfig = d->buildConfiguration; const QString buildVariant = expandedConfig.value(QLatin1String("qbs.buildVariant")).toString(); if (buildVariant.isEmpty()) - throw Error(Internal::Tr::tr("No build variant set.")); + throw ErrorInfo(Internal::Tr::tr("No build variant set.")); if (buildVariant != QLatin1String("debug") && buildVariant != QLatin1String("release")) { err.append(Internal::Tr::tr("Invalid build variant '%1'. Must be 'debug' or 'release'.") .arg(buildVariant)); diff --git a/src/lib/tools/setupprojectparameters.h b/src/lib/tools/setupprojectparameters.h index db400c2c3..c262930f6 100644 --- a/src/lib/tools/setupprojectparameters.h +++ b/src/lib/tools/setupprojectparameters.h @@ -68,7 +68,7 @@ public: QVariantMap buildConfiguration() const; void setBuildConfiguration(const QVariantMap &buildConfiguration); QVariantMap buildConfigurationTree() const; - Error expandBuildConfiguration(Settings *settings); + ErrorInfo expandBuildConfiguration(Settings *settings); bool ignoreDifferentProjectFilePath() const; void setIgnoreDifferentProjectFilePath(bool doIgnore); diff --git a/src/lib/tools/tst_tools.cpp b/src/lib/tools/tst_tools.cpp index e19099a13..68789e29e 100644 --- a/src/lib/tools/tst_tools.cpp +++ b/src/lib/tools/tst_tools.cpp @@ -103,7 +103,7 @@ void TestTools::testProfiles() childProfile.setBaseProfile("foo"); QCOMPARE(childProfile.value("testKey", "none").toString(), QLatin1String("gnampf")); exceptionCaught = false; - } catch (Error &) { + } catch (ErrorInfo &) { exceptionCaught = true; } QVERIFY(!exceptionCaught); @@ -112,7 +112,7 @@ void TestTools::testProfiles() childProfile.setBaseProfile("SmurfAlongWithMe"); childProfile.value("blubb"); exceptionCaught = false; - } catch (Error &) { + } catch (ErrorInfo &) { exceptionCaught = true; } QVERIFY(exceptionCaught); @@ -122,7 +122,7 @@ void TestTools::testProfiles() parentProfile.setBaseProfile("child"); QVERIFY(!childProfile.value("blubb").isValid()); exceptionCaught = false; - } catch (Error &) { + } catch (ErrorInfo &) { exceptionCaught = true; } QVERIFY(exceptionCaught); @@ -130,7 +130,7 @@ void TestTools::testProfiles() try { QVERIFY(!childProfile.allKeys(Profile::KeySelectionNonRecursive).isEmpty()); exceptionCaught = false; - } catch (Error &) { + } catch (ErrorInfo &) { exceptionCaught = true; } QVERIFY(!exceptionCaught); @@ -138,7 +138,7 @@ void TestTools::testProfiles() try { QVERIFY(!childProfile.allKeys(Profile::KeySelectionRecursive).isEmpty()); exceptionCaught = false; - } catch (Error &) { + } catch (ErrorInfo &) { exceptionCaught = true; } QVERIFY(exceptionCaught); |
