diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2016-09-08 15:29:30 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2016-09-30 09:12:42 +0000 |
commit | 96b501d80e539a832ef9f2bef4f34162eb8ad3e2 (patch) | |
tree | 4b5c54efa27a0a50ee4e874334671e0856593227 | |
parent | bf3a7979a41b166b8dc178a3cc6a22f15a4e6ea5 (diff) |
Re-display warnings when loading a stored build graph
[ChangeLog] Warnings encountered during project resolving are now stored
and will be re-displayed when the project is loaded.
Task-number: QBS-1011
Change-Id: I5fa04d3d537866212abbdf739b09a254843de473
Reviewed-by: Jake Petroules <jake.petroules@qt.io>
37 files changed, 197 insertions, 47 deletions
diff --git a/src/lib/corelib/api/runenvironment.cpp b/src/lib/corelib/api/runenvironment.cpp index 0293a93da..7398be29e 100644 --- a/src/lib/corelib/api/runenvironment.cpp +++ b/src/lib/corelib/api/runenvironment.cpp @@ -72,21 +72,21 @@ class RunEnvironment::RunEnvironmentPrivate public: RunEnvironmentPrivate(const ResolvedProductPtr &product, const InstallOptions &installOptions, const QProcessEnvironment &environment, Settings *settings, const Logger &logger) - : engine(logger) - , resolvedProduct(product) + : resolvedProduct(product) , installOptions(installOptions) , environment(environment) , settings(settings) , logger(logger) + , engine(this->logger) { } - ScriptEngine engine; const ResolvedProductPtr resolvedProduct; InstallOptions installOptions; const QProcessEnvironment environment; Settings * const settings; Logger logger; + ScriptEngine engine; }; RunEnvironment::RunEnvironment(const ResolvedProductPtr &product, diff --git a/src/lib/corelib/buildgraph/buildgraphloader.cpp b/src/lib/corelib/buildgraph/buildgraphloader.cpp index 902334ba5..067460865 100644 --- a/src/lib/corelib/buildgraph/buildgraphloader.cpp +++ b/src/lib/corelib/buildgraph/buildgraphloader.cpp @@ -112,8 +112,11 @@ BuildGraphLoadResult BuildGraphLoader::load(const TopLevelProjectPtr &existingPr } if (!m_result.loadedProject) return m_result; - if (parameters.restoreBehavior() == SetupProjectParameters::RestoreOnly) + if (parameters.restoreBehavior() == SetupProjectParameters::RestoreOnly) { + foreach (const ErrorInfo &e, existingProject->warningsEncountered) + m_logger.printWarning(e); return m_result; + } QBS_CHECK(parameters.restoreBehavior() == SetupProjectParameters::RestoreAndTrackChanges); trackProjectChanges(); @@ -233,8 +236,11 @@ void BuildGraphLoader::trackProjectChanges() reResolvingNecessary = true; } - if (!reResolvingNecessary) + if (!reResolvingNecessary) { + foreach (const ErrorInfo &e, restoredProject->warningsEncountered) + m_logger.printWarning(e); return; + } restoredProject->buildData->isDirty = true; Loader ldr(m_evalContext->engine(), m_logger); diff --git a/src/lib/corelib/buildgraph/depscanner.cpp b/src/lib/corelib/buildgraph/depscanner.cpp index 02c63ce5d..494c6cc1d 100644 --- a/src/lib/corelib/buildgraph/depscanner.cpp +++ b/src/lib/corelib/buildgraph/depscanner.cpp @@ -144,7 +144,7 @@ UserDependencyScanner::UserDependencyScanner(const ResolvedScannerConstPtr &scan const Logger &logger) : m_scanner(scanner), m_logger(logger), - m_engine(new ScriptEngine(logger)), + m_engine(new ScriptEngine(m_logger)), m_observer(m_engine), m_product(0) { diff --git a/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp b/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp index 5a5c00236..e2a8d29ec 100644 --- a/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp +++ b/src/lib/corelib/buildgraph/rulesevaluationcontext.cpp @@ -55,7 +55,7 @@ namespace qbs { namespace Internal { RulesEvaluationContext::RulesEvaluationContext(const Logger &logger) - : m_engine(new ScriptEngine(logger)), m_observer(0), m_initScopeCalls(0) + : m_logger(logger), m_engine(new ScriptEngine(m_logger)), m_observer(0), m_initScopeCalls(0) { m_prepareScriptScope = m_engine->newObject(); m_prepareScriptScope.setPrototype(m_engine->globalObject()); diff --git a/src/lib/corelib/buildgraph/rulesevaluationcontext.h b/src/lib/corelib/buildgraph/rulesevaluationcontext.h index 7a994a2e8..db475296a 100644 --- a/src/lib/corelib/buildgraph/rulesevaluationcontext.h +++ b/src/lib/corelib/buildgraph/rulesevaluationcontext.h @@ -40,6 +40,7 @@ #define QBS_RULESEVALUATIONCONTEXT_H #include <language/forward_decls.h> +#include <logging/logger.h> #include <QHash> #include <QScriptProgram> @@ -48,7 +49,6 @@ namespace qbs { namespace Internal { -class Logger; class ProgressObserver; class ScriptEngine; @@ -84,6 +84,7 @@ private: void initScope(); void cleanupScope(); + Logger m_logger; ScriptEngine * const m_engine; ProgressObserver *m_observer; unsigned int m_initScopeCalls; diff --git a/src/lib/corelib/language/evaluator.cpp b/src/lib/corelib/language/evaluator.cpp index 02430da3c..13f69a5f1 100644 --- a/src/lib/corelib/language/evaluator.cpp +++ b/src/lib/corelib/language/evaluator.cpp @@ -58,7 +58,7 @@ namespace qbs { namespace Internal { -Evaluator::Evaluator(ScriptEngine *scriptEngine, const Logger &logger) +Evaluator::Evaluator(ScriptEngine *scriptEngine, Logger &logger) : m_scriptEngine(scriptEngine) , m_scriptClass(new EvaluatorScriptClass(scriptEngine, logger)) { diff --git a/src/lib/corelib/language/evaluator.h b/src/lib/corelib/language/evaluator.h index f8e4a7702..49262d8a5 100644 --- a/src/lib/corelib/language/evaluator.h +++ b/src/lib/corelib/language/evaluator.h @@ -58,7 +58,7 @@ class Evaluator : private ItemObserver friend class SVConverter; public: - Evaluator(ScriptEngine *scriptEngine, const Logger &logger); + Evaluator(ScriptEngine *scriptEngine, Logger &logger); virtual ~Evaluator(); ScriptEngine *engine() const { return m_scriptEngine; } diff --git a/src/lib/corelib/language/evaluatorscriptclass.cpp b/src/lib/corelib/language/evaluatorscriptclass.cpp index 323b4cbdc..bf14b2772 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.cpp +++ b/src/lib/corelib/language/evaluatorscriptclass.cpp @@ -287,7 +287,7 @@ enum QueryPropertyType QPTParentProperty }; -EvaluatorScriptClass::EvaluatorScriptClass(ScriptEngine *scriptEngine, const Logger &logger) +EvaluatorScriptClass::EvaluatorScriptClass(ScriptEngine *scriptEngine, Logger &logger) : QScriptClass(scriptEngine) , m_logger(logger) , m_valueCacheEnabled(false) diff --git a/src/lib/corelib/language/evaluatorscriptclass.h b/src/lib/corelib/language/evaluatorscriptclass.h index c1e2d62ea..d17428c3f 100644 --- a/src/lib/corelib/language/evaluatorscriptclass.h +++ b/src/lib/corelib/language/evaluatorscriptclass.h @@ -61,7 +61,7 @@ class ScriptEngine; class EvaluatorScriptClass : public QScriptClass { public: - EvaluatorScriptClass(ScriptEngine *scriptEngine, const Logger &logger); + EvaluatorScriptClass(ScriptEngine *scriptEngine, Logger &logger); QueryFlags queryProperty(const QScriptValue &object, const QScriptString &name, @@ -94,7 +94,7 @@ private: ValuePtr value; }; QueryResult m_queryResult; - Logger m_logger; + Logger &m_logger; bool m_valueCacheEnabled; QStack<JSSourceValue *> m_sourceValueStack; QSet<Value *> m_currentNextChain; diff --git a/src/lib/corelib/language/itemreader.cpp b/src/lib/corelib/language/itemreader.cpp index e0add0111..6386aaebc 100644 --- a/src/lib/corelib/language/itemreader.cpp +++ b/src/lib/corelib/language/itemreader.cpp @@ -44,7 +44,7 @@ namespace qbs { namespace Internal { -ItemReader::ItemReader(const Logger &logger) : m_visitorState(new ItemReaderVisitorState(logger)) +ItemReader::ItemReader(Logger &logger) : m_visitorState(new ItemReaderVisitorState(logger)) { } diff --git a/src/lib/corelib/language/itemreader.h b/src/lib/corelib/language/itemreader.h index 640bd586c..091aa6734 100644 --- a/src/lib/corelib/language/itemreader.h +++ b/src/lib/corelib/language/itemreader.h @@ -66,7 +66,7 @@ class ItemReaderVisitorState; class ItemReader { public: - ItemReader(const Logger &logger); + ItemReader(Logger &logger); ~ItemReader(); void setPool(ItemPool *pool) { m_pool = pool; } diff --git a/src/lib/corelib/language/itemreaderastvisitor.cpp b/src/lib/corelib/language/itemreaderastvisitor.cpp index 08d045d82..15d8768c7 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.cpp +++ b/src/lib/corelib/language/itemreaderastvisitor.cpp @@ -64,7 +64,7 @@ namespace qbs { namespace Internal { ItemReaderASTVisitor::ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, - const FileContextPtr &file, ItemPool *itemPool, Logger logger) + const FileContextPtr &file, ItemPool *itemPool, Logger &logger) : m_visitorState(visitorState) , m_file(file) , m_itemPool(itemPool) diff --git a/src/lib/corelib/language/itemreaderastvisitor.h b/src/lib/corelib/language/itemreaderastvisitor.h index 4277f6dab..96d3f9e3b 100644 --- a/src/lib/corelib/language/itemreaderastvisitor.h +++ b/src/lib/corelib/language/itemreaderastvisitor.h @@ -61,7 +61,7 @@ class ItemReaderASTVisitor : public QbsQmlJS::AST::Visitor { public: ItemReaderASTVisitor(ItemReaderVisitorState &visitorState, const FileContextPtr &file, - ItemPool *itemPool, Logger logger); + ItemPool *itemPool, Logger &logger); void checkItemTypes() { doCheckItemTypes(rootItem()); } Item *rootItem() const { return m_item; } @@ -86,7 +86,7 @@ private: ItemReaderVisitorState &m_visitorState; const FileContextPtr m_file; ItemPool * const m_itemPool; - Logger m_logger; + Logger &m_logger; QHash<QStringList, QString> m_typeNameToFile; Item *m_item = nullptr; }; diff --git a/src/lib/corelib/language/itemreadervisitorstate.cpp b/src/lib/corelib/language/itemreadervisitorstate.cpp index 6a72902d6..7c0ddd6e4 100644 --- a/src/lib/corelib/language/itemreadervisitorstate.cpp +++ b/src/lib/corelib/language/itemreadervisitorstate.cpp @@ -105,7 +105,7 @@ private: class ItemReaderVisitorState::ASTCache : public QHash<QString, ASTCacheValue> {}; -ItemReaderVisitorState::ItemReaderVisitorState(Logger logger) +ItemReaderVisitorState::ItemReaderVisitorState(Logger &logger) : m_logger(logger) , m_astCache(new ASTCache) { diff --git a/src/lib/corelib/language/itemreadervisitorstate.h b/src/lib/corelib/language/itemreadervisitorstate.h index 9edd953cf..261436eb1 100644 --- a/src/lib/corelib/language/itemreadervisitorstate.h +++ b/src/lib/corelib/language/itemreadervisitorstate.h @@ -53,7 +53,7 @@ class ItemPool; class ItemReaderVisitorState { public: - ItemReaderVisitorState(Logger logger); + ItemReaderVisitorState(Logger &logger); ~ItemReaderVisitorState(); QSet<QString> filesRead() const { return m_filesRead; } @@ -64,7 +64,7 @@ public: bool findDirectoryEntries(const QString &dirPath, QStringList *entries) const; private: - Logger m_logger; + Logger &m_logger; QSet<QString> m_filesRead; QHash<QString, QStringList> m_directoryEntries; diff --git a/src/lib/corelib/language/language.cpp b/src/lib/corelib/language/language.cpp index f36375771..47099a0f0 100644 --- a/src/lib/corelib/language/language.cpp +++ b/src/lib/corelib/language/language.cpp @@ -67,6 +67,8 @@ #include <QMutexLocker> #include <QScriptValue> +#include <algorithm> + namespace qbs { namespace Internal { @@ -974,7 +976,7 @@ QString TopLevelProject::buildGraphFilePath() const return ProjectBuildData::deriveBuildGraphFilePath(buildDirectory, id()); } -void TopLevelProject::store(const Logger &logger) const +void TopLevelProject::store(Logger logger) const { // TODO: Use progress observer here. @@ -1012,6 +1014,13 @@ void TopLevelProject::load(PersistentPool &pool) pool.stream() >> profileConfigs; pool.stream() >> buildSystemFiles; pool.stream() >> lastResolveTime; + int warningsCount; + pool.stream() >> warningsCount; + for (int i = 0; i < warningsCount; ++i) { + ErrorInfo e; + e.load(pool); + warningsEncountered << e; + } buildData.reset(pool.idLoad<ProjectBuildData>()); QBS_CHECK(buildData); buildData->isDirty = false; @@ -1033,6 +1042,9 @@ void TopLevelProject::store(PersistentPool &pool) const pool.stream() << profileConfigs; pool.stream() << buildSystemFiles; pool.stream() << lastResolveTime; + pool.stream() << warningsEncountered.count(); + std::for_each(warningsEncountered.constBegin(), warningsEncountered.constEnd(), + [&pool](const ErrorInfo &e) { e.store(pool); }); pool.store(buildData.data()); } diff --git a/src/lib/corelib/language/language.h b/src/lib/corelib/language/language.h index ed6271eb0..8d5c401f8 100644 --- a/src/lib/corelib/language/language.h +++ b/src/lib/corelib/language/language.h @@ -499,6 +499,7 @@ public: QSet<QString> buildSystemFiles; FileTime lastResolveTime; + QList<ErrorInfo> warningsEncountered; void setBuildConfiguration(const QVariantMap &config); const QVariantMap &buildConfiguration() const { return m_buildConfiguration; } @@ -507,7 +508,7 @@ public: QVariantMap profileConfigs; QString buildGraphFilePath() const; - void store(const Logger &logger) const; + void store(Logger logger) const; private: TopLevelProject(); diff --git a/src/lib/corelib/language/loader.cpp b/src/lib/corelib/language/loader.cpp index 93e9eaa6d..29eff18a1 100644 --- a/src/lib/corelib/language/loader.cpp +++ b/src/lib/corelib/language/loader.cpp @@ -62,6 +62,7 @@ Loader::Loader(ScriptEngine *engine, const Logger &logger) , m_progressObserver(0) , m_engine(engine) { + m_logger.storeWarnings(); } void Loader::setProgressObserver(ProgressObserver *observer) @@ -97,6 +98,7 @@ TopLevelProjectPtr Loader::loadProject(const SetupProjectParameters ¶meters) m_engine->clearExceptions(); m_engine->clearImportsCache(); m_engine->clearRequestedProperties(); + m_logger.clearWarnings(); QTimer cancelationTimer; diff --git a/src/lib/corelib/language/moduleloader.cpp b/src/lib/corelib/language/moduleloader.cpp index d2ce94631..d9fb738a1 100644 --- a/src/lib/corelib/language/moduleloader.cpp +++ b/src/lib/corelib/language/moduleloader.cpp @@ -173,7 +173,7 @@ private: }; ModuleLoader::ModuleLoader(ScriptEngine *engine, - const Logger &logger) + Logger &logger) : m_engine(engine) , m_pool(0) , m_logger(logger) @@ -262,7 +262,7 @@ ModuleLoaderResult ModuleLoader::load(const SetupProjectParameters ¶meters) } static void handlePropertyError(const ErrorInfo &error, const SetupProjectParameters ¶ms, - Logger logger) + Logger &logger) { if (params.propertyCheckingMode() == ErrorHandlingMode::Strict) throw error; @@ -275,10 +275,10 @@ class PropertyDeclarationCheck : public ValueHandler Item *m_parentItem; QString m_currentName; SetupProjectParameters m_params; - Logger m_logger; + Logger &m_logger; public: PropertyDeclarationCheck(const QSet<Item *> &disabledItems, - const SetupProjectParameters ¶ms, const Logger &logger) + const SetupProjectParameters ¶ms, Logger &logger) : m_disabledItems(disabledItems) , m_parentItem(0) , m_params(params) diff --git a/src/lib/corelib/language/moduleloader.h b/src/lib/corelib/language/moduleloader.h index 840e04bb0..8f576786d 100644 --- a/src/lib/corelib/language/moduleloader.h +++ b/src/lib/corelib/language/moduleloader.h @@ -112,7 +112,7 @@ struct ModuleLoaderResult class ModuleLoader { public: - ModuleLoader(ScriptEngine *engine, const Logger &logger); + ModuleLoader(ScriptEngine *engine, Logger &logger); ~ModuleLoader(); void setProgressObserver(ProgressObserver *progressObserver); @@ -264,7 +264,7 @@ private: ScriptEngine *m_engine; ItemPool *m_pool; - Logger m_logger; + Logger &m_logger; ProgressObserver *m_progressObserver; ItemReader *m_reader; Evaluator *m_evaluator; diff --git a/src/lib/corelib/language/modulemerger.cpp b/src/lib/corelib/language/modulemerger.cpp index baa0030e8..fa082ac16 100644 --- a/src/lib/corelib/language/modulemerger.cpp +++ b/src/lib/corelib/language/modulemerger.cpp @@ -47,7 +47,7 @@ namespace qbs { namespace Internal { -ModuleMerger::ModuleMerger(const Logger &logger, Item *root, Item::Module &moduleToMerge) +ModuleMerger::ModuleMerger(Logger &logger, Item *root, Item::Module &moduleToMerge) : m_logger(logger) , m_rootItem(root) , m_mergedModule(moduleToMerge) diff --git a/src/lib/corelib/language/modulemerger.h b/src/lib/corelib/language/modulemerger.h index c17e9df6b..479ad3008 100644 --- a/src/lib/corelib/language/modulemerger.h +++ b/src/lib/corelib/language/modulemerger.h @@ -54,7 +54,7 @@ namespace Internal { class ModuleMerger { public: - ModuleMerger(const Logger &logger, Item *root, Item::Module &moduleToMerge); + ModuleMerger(Logger &logger, Item *root, Item::Module &moduleToMerge); void start(); private: @@ -69,7 +69,7 @@ private: void replaceItemInValues(QualifiedId moduleName, Item *containerItem, Item *toReplace); void replaceItemInScopes(Item *toReplace); - const Logger &m_logger; + Logger &m_logger; Item * const m_rootItem; Item::Module &m_mergedModule; Item *m_clonedModulePrototype = nullptr; diff --git a/src/lib/corelib/language/projectresolver.cpp b/src/lib/corelib/language/projectresolver.cpp index 21c9c06f6..2a648a70b 100644 --- a/src/lib/corelib/language/projectresolver.cpp +++ b/src/lib/corelib/language/projectresolver.cpp @@ -103,7 +103,7 @@ struct ProjectResolver::ModuleContext ProjectResolver::ProjectResolver(Evaluator *evaluator, const ModuleLoaderResult &loadResult, - const SetupProjectParameters &setupParameters, const Logger &logger) + const SetupProjectParameters &setupParameters, Logger &logger) : m_evaluator(evaluator) , m_logger(logger) , m_engine(m_evaluator->engine()) @@ -249,6 +249,7 @@ TopLevelProjectPtr ProjectResolver::resolveTopLevelProject() artifact->fileTags += "installable"; } } + project->warningsEncountered = m_logger.warnings(); return project; } @@ -1033,7 +1034,7 @@ void ProjectResolver::applyFileTaggers(const ResolvedProductPtr &product) const } void ProjectResolver::applyFileTaggers(const SourceArtifactPtr &artifact, - const ResolvedProductConstPtr &product, const Logger &logger) + const ResolvedProductConstPtr &product, Logger &logger) { if (!artifact->overrideFileTags || artifact->fileTags.isEmpty()) { const QString fileName = FileInfo::fileName(artifact->absoluteFilePath); diff --git a/src/lib/corelib/language/projectresolver.h b/src/lib/corelib/language/projectresolver.h index 35620b382..820cc2a20 100644 --- a/src/lib/corelib/language/projectresolver.h +++ b/src/lib/corelib/language/projectresolver.h @@ -62,14 +62,14 @@ class ProjectResolver { public: ProjectResolver(Evaluator *evaluator, const ModuleLoaderResult &loadResult, - const SetupProjectParameters &setupParameters, const Logger &logger); + const SetupProjectParameters &setupParameters, Logger &logger); ~ProjectResolver(); void setProgressObserver(ProgressObserver *observer); TopLevelProjectPtr resolve(); static void applyFileTaggers(const SourceArtifactPtr &artifact, - const ResolvedProductConstPtr &product, const Logger &logger); + const ResolvedProductConstPtr &product, Logger &logger); static SourceArtifactPtr createSourceArtifact(const ResolvedProductConstPtr &rproduct, const QString &fileName, const GroupPtr &group, bool wildcard, @@ -119,7 +119,7 @@ private: const QList<SourceArtifactPtr> &artifacts); Evaluator *m_evaluator; - Logger m_logger; + Logger &m_logger; ScriptEngine *m_engine; ProgressObserver *m_progressObserver; ProductContext *m_productContext; diff --git a/src/lib/corelib/language/scriptengine.cpp b/src/lib/corelib/language/scriptengine.cpp index 7b78539b4..75b7c8aab 100644 --- a/src/lib/corelib/language/scriptengine.cpp +++ b/src/lib/corelib/language/scriptengine.cpp @@ -86,7 +86,7 @@ uint qHash(const ScriptEngine::PropertyCacheKey &k, uint seed = 0) combineHash(qHash(k.m_propertyName), qHash(k.m_propertyMap), seed), seed); } -ScriptEngine::ScriptEngine(const Logger &logger, QObject *parent) +ScriptEngine::ScriptEngine(Logger &logger, QObject *parent) : QScriptEngine(parent), m_scriptImporter(new ScriptImporter(this)), m_propertyCacheEnabled(true), m_logger(logger) { diff --git a/src/lib/corelib/language/scriptengine.h b/src/lib/corelib/language/scriptengine.h index 40793e753..192d337b5 100644 --- a/src/lib/corelib/language/scriptengine.h +++ b/src/lib/corelib/language/scriptengine.h @@ -64,11 +64,10 @@ class ScriptEngine : public QScriptEngine { Q_OBJECT public: - ScriptEngine(const Logger &logger, QObject *parent = 0); + ScriptEngine(Logger &logger, QObject *parent = 0); ~ScriptEngine(); - void setLogger(const Logger &logger) { m_logger = logger; } - Logger logger() const { return m_logger; } + Logger &logger() const { return m_logger; } void import(const FileContextBaseConstPtr &fileCtx, QScriptValue &targetObject); void import(const JsImport &jsImport, QScriptValue &targetObject); void clearImportsCache(); @@ -172,7 +171,7 @@ private: QHash<PropertyCacheKey, QVariant> m_propertyCache; PropertySet m_propertiesRequestedInScript; QHash<QString, PropertySet> m_propertiesRequestedFromArtifact; - Logger m_logger; + Logger &m_logger; QScriptValue m_definePropertyFunction; QScriptValue m_emptyFunction; QProcessEnvironment m_environment; diff --git a/src/lib/corelib/logging/logger.cpp b/src/lib/corelib/logging/logger.cpp index 0d397e36d..866ad8b00 100644 --- a/src/lib/corelib/logging/logger.cpp +++ b/src/lib/corelib/logging/logger.cpp @@ -213,6 +213,13 @@ bool Logger::traceEnabled() const return m_logSink->willPrint(LoggerTrace); } +void Logger::printWarning(const ErrorInfo &warning) +{ + if (m_storeWarnings) + m_warnings << warning; + logSink()->printWarning(warning); +} + LogWriter Logger::qbsLog(LoggerLevel level, bool force) const { return LogWriter(m_logSink, level, force); diff --git a/src/lib/corelib/logging/logger.h b/src/lib/corelib/logging/logger.h index 23884dfba..2e3edc880 100644 --- a/src/lib/corelib/logging/logger.h +++ b/src/lib/corelib/logging/logger.h @@ -42,6 +42,8 @@ #include "ilogsink.h" +#include <tools/error.h> + #include <QByteArray> #include <QString> #include <QStringList> @@ -104,6 +106,7 @@ QBS_EXPORT LogWriter operator<<(LogWriter w, qint64 n); QBS_EXPORT LogWriter operator<<(LogWriter w, bool b); QBS_EXPORT LogWriter operator<<(LogWriter w, const MessageTag &tag); + class QBS_EXPORT Logger { public: @@ -114,7 +117,10 @@ public: bool debugEnabled() const; bool traceEnabled() const; - void printWarning(const ErrorInfo &warning) { logSink()->printWarning(warning); } + void printWarning(const ErrorInfo &warning); + QList<ErrorInfo> warnings() const { return m_warnings; } + void clearWarnings() { m_warnings.clear(); } + void storeWarnings() { m_storeWarnings = true; } LogWriter qbsLog(LoggerLevel level, bool force = false) const; LogWriter qbsWarning() const { return qbsLog(LoggerWarning); } @@ -124,6 +130,8 @@ public: private: ILogSink *m_logSink; + QList<ErrorInfo> m_warnings; + bool m_storeWarnings = false; }; diff --git a/src/lib/corelib/tools/error.cpp b/src/lib/corelib/tools/error.cpp index 2930e0df8..394fd8c88 100644 --- a/src/lib/corelib/tools/error.cpp +++ b/src/lib/corelib/tools/error.cpp @@ -39,10 +39,15 @@ #include "error.h" +#include "persistence.h" + #include <QRegularExpression> #include <QSharedData> #include <QStringList> +#include <algorithm> +#include <functional> + namespace qbs { class ErrorItem::ErrorItemPrivate : public QSharedData @@ -102,6 +107,20 @@ bool ErrorItem::isBacktraceItem() const return d->isBacktraceItem; } +void ErrorItem::load(Internal::PersistentPool &pool) +{ + d->description = pool.idLoadString(); + d->codeLocation.load(pool); + pool.stream() >> d->isBacktraceItem; +} + +void ErrorItem::store(Internal::PersistentPool &pool) const +{ + pool.storeString(d->description); + d->codeLocation.store(pool); + pool.stream() << d->isBacktraceItem; +} + /*! * \fn const QString &ErrorData::description() const * \brief A general description of the error. @@ -245,4 +264,24 @@ bool ErrorInfo::isInternalError() const return d->internalError; } +void ErrorInfo::load(Internal::PersistentPool &pool) +{ + int itemCount; + pool.stream() >> itemCount; + for (int i = 0; i < itemCount; ++i) { + ErrorItem e; + e.load(pool); + d->items << e; + } + pool.stream() >> d->internalError; +} + +void ErrorInfo::store(Internal::PersistentPool &pool) const +{ + pool.stream() << d->items.count(); + std::for_each(d->items.constBegin(), d->items.constEnd(), + [&pool](const ErrorItem &e) { e.store(pool); }); + pool.stream() << d->internalError; +} + } // namespace qbs diff --git a/src/lib/corelib/tools/error.h b/src/lib/corelib/tools/error.h index c2bf575dd..7ba94aae8 100644 --- a/src/lib/corelib/tools/error.h +++ b/src/lib/corelib/tools/error.h @@ -52,6 +52,7 @@ class QString; QT_END_NAMESPACE namespace qbs { +namespace Internal { class PersistentPool; } class CodeLocation; class QBS_EXPORT ErrorItem @@ -69,6 +70,9 @@ public: bool isBacktraceItem() const; + void load(Internal::PersistentPool &pool); + void store(Internal::PersistentPool &pool) const; + private: ErrorItem(const QString &description, const CodeLocation &codeLocation, bool isBacktraceItem = false); @@ -97,6 +101,9 @@ public: QString toString() const; bool isInternalError() const; + void load(Internal::PersistentPool &pool); + void store(Internal::PersistentPool &pool) const; + private: class ErrorInfoPrivate; QSharedDataPointer<ErrorInfoPrivate> d; diff --git a/src/lib/corelib/tools/persistence.cpp b/src/lib/corelib/tools/persistence.cpp index a4303c2e6..72d362d91 100644 --- a/src/lib/corelib/tools/persistence.cpp +++ b/src/lib/corelib/tools/persistence.cpp @@ -50,9 +50,9 @@ namespace qbs { namespace Internal { -static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-89"; +static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-90"; -PersistentPool::PersistentPool(const Logger &logger) : m_logger(logger) +PersistentPool::PersistentPool(Logger &logger) : m_logger(logger) { m_stream.setVersion(QDataStream::Qt_4_8); } diff --git a/src/lib/corelib/tools/persistence.h b/src/lib/corelib/tools/persistence.h index 76348b438..70e94a870 100644 --- a/src/lib/corelib/tools/persistence.h +++ b/src/lib/corelib/tools/persistence.h @@ -55,7 +55,7 @@ namespace Internal { class PersistentPool { public: - PersistentPool(const Logger &logger); + PersistentPool(Logger &logger); ~PersistentPool(); class HeadData @@ -122,7 +122,7 @@ private: QVector<QString> m_stringStorage; QHash<QString, int> m_inverseStringStorage; PersistentObjectId m_lastStoredStringId; - Logger m_logger; + Logger &m_logger; }; template <typename T> inline T *PersistentPool::idLoad() diff --git a/tests/auto/api/testdata/restored-warnings/file.cpp b/tests/auto/api/testdata/restored-warnings/file.cpp new file mode 100644 index 000000000..56757a701 --- /dev/null +++ b/tests/auto/api/testdata/restored-warnings/file.cpp @@ -0,0 +1 @@ +void f() {} diff --git a/tests/auto/api/testdata/restored-warnings/main.cpp b/tests/auto/api/testdata/restored-warnings/main.cpp new file mode 100644 index 000000000..237c8ce18 --- /dev/null +++ b/tests/auto/api/testdata/restored-warnings/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs b/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs new file mode 100644 index 000000000..2de943eda --- /dev/null +++ b/tests/auto/api/testdata/restored-warnings/restored-warnings.qbs @@ -0,0 +1,15 @@ +import qbs +import qbs.Process 1.5 + +CppApplication { + name: "theProduct" + + property bool moreFiles: false + cpp.blubb: true + + files: ["file.cpp", "main.cpp"] + Group { + condition: moreFiles + files: ["blubb.cpp"] + } +} diff --git a/tests/auto/api/tst_api.cpp b/tests/auto/api/tst_api.cpp index 88582fd15..cada604f3 100644 --- a/tests/auto/api/tst_api.cpp +++ b/tests/auto/api/tst_api.cpp @@ -1947,6 +1947,55 @@ void TestApi::resolveProjectDryRun_data() return resolveProject_data(); } +void TestApi::restoredWarnings() +{ + qbs::SetupProjectParameters setupParams + = defaultSetupParameters("restored-warnings/restored-warnings.qbs"); + setupParams.setPropertyCheckingMode(qbs::ErrorHandlingMode::Relaxed); + setupParams.setProductErrorMode(qbs::ErrorHandlingMode::Relaxed); + + // Initial resolving: Errors are new. + QScopedPointer<qbs::SetupProjectJob> job(qbs::Project().setupProject(setupParams, + m_logSink, 0)); + waitForFinished(job.data()); + QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString())); + job.reset(nullptr); + QCOMPARE(m_logSink->warnings.count(), 2); + foreach (const qbs::ErrorInfo &e, m_logSink->warnings) { + const QString msg = e.toString(); + QVERIFY2(msg.contains("Superfluous version") + || msg.contains("Property 'blubb' is not declared"), + qPrintable(msg)); + } + m_logSink->warnings.clear(); + + // Re-resolving with no changes: Errors come from the stored build graph. + job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0)); + waitForFinished(job.data()); + QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString())); + job.reset(nullptr); + QCOMPARE(m_logSink->warnings.count(), 2); + m_logSink->warnings.clear(); + + // Re-resolving with changes: Errors come from the re-resolving, stored ones must be suppressed. + QVariantMap overridenValues; + overridenValues.insert("theProduct.moreFiles", true); + setupParams.setOverriddenValues(overridenValues); + job.reset(qbs::Project().setupProject(setupParams, m_logSink, 0)); + waitForFinished(job.data()); + QVERIFY2(!job->error().hasError(), qPrintable(job->error().toString())); + job.reset(nullptr); + QCOMPARE(m_logSink->warnings.count(), 4); // One more for the additional group + foreach (const qbs::ErrorInfo &e, m_logSink->warnings) { + const QString msg = e.toString(); + QVERIFY2(msg.contains("Superfluous version") + || msg.contains("Property 'blubb' is not declared") + || msg.contains("blubb.cpp' does not exist"), + qPrintable(msg)); + } + m_logSink->warnings.clear(); +} + void TestApi::ruleConflict() { const qbs::ErrorInfo errorInfo = doBuildProject("rule-conflict/rule-conflict.qbs"); diff --git a/tests/auto/api/tst_api.h b/tests/auto/api/tst_api.h index 4e7f7add3..54aed93e8 100644 --- a/tests/auto/api/tst_api.h +++ b/tests/auto/api/tst_api.h @@ -123,6 +123,7 @@ private slots: void resolveProject_data(); void resolveProjectDryRun(); void resolveProjectDryRun_data(); + void restoredWarnings(); void ruleConflict(); void softDependency(); void sourceFileInBuildDir(); |