diff options
author | Christian Kandeler <christian.kandeler@digia.com> | 2013-07-02 09:53:45 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@digia.com> | 2013-07-03 17:11:05 +0200 |
commit | 97b1e430240845bfa285e6e6574640cbb333b9f8 (patch) | |
tree | 5efeeaf3dc652c52603ddf2b7bee325ba128e453 | |
parent | 8e7fe3fdd97e64893a51dc577f2a45c5a2ff64f2 (diff) |
Make built-in JavaScript extensions available on demand.
This entails the following:
- Project files can get access to built-in extensions in all
contexts via import statements such as "import qbs.TextFile".
- In turn, the automatic injection of these extensions in rules and
probes no longer happens, i.e. one always has to explicitly import the
required extension.
Change-Id: Ib1e42c078354c564e417f80dd47897c7f41e7569
Reviewed-by: Joerg Bornemann <joerg.bornemann@digia.com>
38 files changed, 223 insertions, 43 deletions
diff --git a/share/qbs/imports/qbs/probes/PathProbe.qbs b/share/qbs/imports/qbs/probes/PathProbe.qbs index 05f27ad16..dff8a10e8 100644 --- a/share/qbs/imports/qbs/probes/PathProbe.qbs +++ b/share/qbs/imports/qbs/probes/PathProbe.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.File import qbs.fileinfo as FileInfo import "utils.js" as Utils diff --git a/share/qbs/imports/qbs/probes/PkgConfigProbe.qbs b/share/qbs/imports/qbs/probes/PkgConfigProbe.qbs index aca42f0de..c47a6ada2 100644 --- a/share/qbs/imports/qbs/probes/PkgConfigProbe.qbs +++ b/share/qbs/imports/qbs/probes/PkgConfigProbe.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.Process import qbs.fileinfo as FileInfo import "utils.js" as Utils diff --git a/share/qbs/modules/cpp/DarwinGCC.qbs b/share/qbs/modules/cpp/DarwinGCC.qbs index df21a98f4..b7f793f5f 100644 --- a/share/qbs/modules/cpp/DarwinGCC.qbs +++ b/share/qbs/modules/cpp/DarwinGCC.qbs @@ -1,4 +1,6 @@ import qbs 1.0 +import qbs.Process +import qbs.TextFile import qbs.fileinfo as FileInfo import '../utils.js' as ModUtils import "bundle-tools.js" as BundleTools diff --git a/share/qbs/modules/cpp/ios-gcc.qbs b/share/qbs/modules/cpp/ios-gcc.qbs index 79b49e316..e8aa01cd7 100644 --- a/share/qbs/modules/cpp/ios-gcc.qbs +++ b/share/qbs/modules/cpp/ios-gcc.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.File import qbs.fileinfo as FileInfo import '../utils.js' as ModUtils import 'darwin-tools.js' as DarwinTools diff --git a/share/share.qbs b/share/share.qbs index 1cefa5af1..66fc5f4d4 100644 --- a/share/share.qbs +++ b/share/share.qbs @@ -1,4 +1,5 @@ import qbs +import qbs.File Product { name: "qbs resources" diff --git a/src/lib/buildgraph/buildgraph.cpp b/src/lib/buildgraph/buildgraph.cpp index a52005b4d..3b5bda27e 100644 --- a/src/lib/buildgraph/buildgraph.cpp +++ b/src/lib/buildgraph/buildgraph.cpp @@ -32,6 +32,7 @@ #include "projectbuilddata.h" #include "productbuilddata.h" +#include <jsextensions/jsextensions.h> #include <jsextensions/moduleproperties.h> #include <language/language.h> #include <language/scriptengine.h> @@ -213,6 +214,7 @@ void setupScriptEngineForProduct(ScriptEngine *engine, const ResolvedProductCons productScriptValue.setProperty(QLatin1String("moduleName"), rule->module->name); engine->import(rule->jsImports, targetObject, targetObject); + JsExtensions::setupExtensions(rule->jsExtensions, targetObject); } bool findPath(Artifact *u, Artifact *v, QList<Artifact*> &path) diff --git a/src/lib/buildgraph/jscommandexecutor.cpp b/src/lib/buildgraph/jscommandexecutor.cpp index 93ecfe157..9d8e5af55 100644 --- a/src/lib/buildgraph/jscommandexecutor.cpp +++ b/src/lib/buildgraph/jscommandexecutor.cpp @@ -34,10 +34,6 @@ #include "command.h" #include "transformer.h" -#include <jsextensions/domxml.h> -#include <jsextensions/file.h> -#include <jsextensions/process.h> -#include <jsextensions/textfile.h> #include <language/language.h> #include <language/scriptengine.h> #include <logging/logger.h> @@ -123,11 +119,6 @@ public: ScriptEngine * scriptEngine = m_enginesPerThread.value(currentThread); if (!scriptEngine) { scriptEngine = new ScriptEngine(m_logger); - const QScriptValue extensionObject = scriptEngine->globalObject(); - File::init(extensionObject); - TextFile::init(extensionObject); - Process::init(extensionObject); - DomXml::init(extensionObject); m_enginesPerThread.insert(currentThread, scriptEngine); } else { scriptEngine->setLogger(m_logger); diff --git a/src/lib/buildgraph/projectbuilddata.cpp b/src/lib/buildgraph/projectbuilddata.cpp index 14e20d2df..fbcbf4796 100644 --- a/src/lib/buildgraph/projectbuilddata.cpp +++ b/src/lib/buildgraph/projectbuilddata.cpp @@ -329,6 +329,7 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc transformer->inputs = inputArtifacts; const RulePtr rule = Rule::create(); rule->jsImports = rtrafo->jsImports; + rule->jsExtensions = rtrafo->jsExtensions; ResolvedModulePtr module = ResolvedModule::create(); module->name = rtrafo->module->name; rule->module = module; diff --git a/src/lib/jsextensions/domxml.cpp b/src/lib/jsextensions/domxml.cpp index 514e83411..a4a0c80da 100644 --- a/src/lib/jsextensions/domxml.cpp +++ b/src/lib/jsextensions/domxml.cpp @@ -36,7 +36,7 @@ namespace qbs { namespace Internal { -void DomXml::init(QScriptValue extensionObject) +void initializeJsExtensionXml(QScriptValue extensionObject) { QScriptEngine *engine = extensionObject.engine(); QScriptValue obj = engine->newQMetaObject(&XmlDomDocument::staticMetaObject, engine->newFunction(&XmlDomDocument::ctor)); diff --git a/src/lib/jsextensions/domxml.h b/src/lib/jsextensions/domxml.h index bfa8ddf9a..4b82a6db6 100644 --- a/src/lib/jsextensions/domxml.h +++ b/src/lib/jsextensions/domxml.h @@ -42,10 +42,7 @@ namespace Internal { class XmlDomDocument; -namespace DomXml -{ - void init(QScriptValue extensionObject); -} +void initializeJsExtensionXml(QScriptValue extensionObject); class XmlDomNode: public QObject, public QScriptable { diff --git a/src/lib/jsextensions/file.cpp b/src/lib/jsextensions/file.cpp index 1962fa2ea..4d7515482 100644 --- a/src/lib/jsextensions/file.cpp +++ b/src/lib/jsextensions/file.cpp @@ -38,7 +38,19 @@ namespace qbs { namespace Internal { -void File::init(QScriptValue extensionObject) +class File +{ + friend void initializeJsExtensionFile(QScriptValue extensionObject); + +private: + static QScriptValue js_ctor(QScriptContext *context, QScriptEngine *engine); + static QScriptValue js_copy(QScriptContext *context, QScriptEngine *engine); + static QScriptValue js_exists(QScriptContext *context, QScriptEngine *engine); + static QScriptValue js_remove(QScriptContext *context, QScriptEngine *engine); +}; + + +void initializeJsExtensionFile(QScriptValue extensionObject) { QScriptEngine *engine = extensionObject.engine(); QScriptValue fileObj = engine->newFunction(File::js_ctor); diff --git a/src/lib/jsextensions/file.h b/src/lib/jsextensions/file.h index c27d35b4e..a19f63c46 100644 --- a/src/lib/jsextensions/file.h +++ b/src/lib/jsextensions/file.h @@ -36,17 +36,7 @@ namespace qbs { namespace Internal { -class File -{ -public: - static void init(QScriptValue extensionObject); - -private: - static QScriptValue js_ctor(QScriptContext *context, QScriptEngine *engine); - static QScriptValue js_copy(QScriptContext *context, QScriptEngine *engine); - static QScriptValue js_exists(QScriptContext *context, QScriptEngine *engine); - static QScriptValue js_remove(QScriptContext *context, QScriptEngine *engine); -}; +void initializeJsExtensionFile(QScriptValue extensionObject); } // namespace Internal } // namespace qbs diff --git a/src/lib/jsextensions/jsextensions.cpp b/src/lib/jsextensions/jsextensions.cpp new file mode 100644 index 000000000..15923e6df --- /dev/null +++ b/src/lib/jsextensions/jsextensions.cpp @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "jsextensions.h" + +#include "domxml.h" +#include "file.h" +#include "process.h" +#include "textfile.h" + +namespace qbs { +namespace Internal { + +void JsExtensions::setupExtensions(const QStringList &names, QScriptValue scope) +{ + foreach (const QString &name, names) + initializers().value(name)(scope); +} + +bool JsExtensions::hasExtension(const QString &name) +{ + return initializers().contains(name); +} + +JsExtensions::InitializerMap JsExtensions::initializers() +{ + if (m_initializers.isEmpty()) { + m_initializers.insert(QLatin1String("File"), &initializeJsExtensionFile); + m_initializers.insert(QLatin1String("Process"), &initializeJsExtensionProcess); + m_initializers.insert(QLatin1String("Xml"), &initializeJsExtensionXml); + m_initializers.insert(QLatin1String("TextFile"), &initializeJsExtensionTextFile); + } + return m_initializers; +} + +JsExtensions::InitializerMap JsExtensions::m_initializers; + +} // namespace Internal +} // namespace qbs diff --git a/src/lib/jsextensions/jsextensions.h b/src/lib/jsextensions/jsextensions.h new file mode 100644 index 000000000..b54e1d259 --- /dev/null +++ b/src/lib/jsextensions/jsextensions.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). +** Contact: http://www.qt-project.org/legal +** +** This file is part of the Qt Build Suite. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Digia. For licensing terms and +** conditions see http://qt.digia.com/licensing. For further information +** use the contact form at http://qt.digia.com/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Digia gives you certain additional +** rights. These rights are described in the Digia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef QBS_JSEXTENSIONS_H +#define QBS_JSEXTENSIONS_H + +#include <QHash> +#include <QStringList> + +QT_BEGIN_NAMESPACE +class QScriptValue; +QT_END_NAMESPACE + +namespace qbs { +namespace Internal { + +class JsExtensions +{ +public: + static void setupExtensions(const QStringList &names, QScriptValue scope); + static bool hasExtension(const QString &name); + +private: + typedef QHash<QString, void (*)(QScriptValue)> InitializerMap; + static InitializerMap initializers(); + + static InitializerMap m_initializers; +}; + +} // namespace Internal +} // namespace qbs + +#endif // Include guard. diff --git a/src/lib/jsextensions/jsextensions.pri b/src/lib/jsextensions/jsextensions.pri index a46fe97c8..21c97ef64 100644 --- a/src/lib/jsextensions/jsextensions.pri +++ b/src/lib/jsextensions/jsextensions.pri @@ -5,11 +5,13 @@ HEADERS += \ $$PWD/textfile.h \ $$PWD/process.h \ $$PWD/moduleproperties.h \ - $$PWD/domxml.h + $$PWD/domxml.h \ + $$PWD/jsextensions.h SOURCES += \ $$PWD/file.cpp \ $$PWD/textfile.cpp \ $$PWD/process.cpp \ $$PWD/moduleproperties.cpp \ - $$PWD/domxml.cpp + $$PWD/domxml.cpp \ + $$PWD/jsextensions.cpp diff --git a/src/lib/jsextensions/process.cpp b/src/lib/jsextensions/process.cpp index 3938192d6..42f59fd7d 100644 --- a/src/lib/jsextensions/process.cpp +++ b/src/lib/jsextensions/process.cpp @@ -41,7 +41,7 @@ namespace qbs { namespace Internal { -void Process::init(QScriptValue extensionObject) +void initializeJsExtensionProcess(QScriptValue extensionObject) { QScriptEngine *engine = extensionObject.engine(); QScriptValue obj = engine->newQMetaObject(&Process::staticMetaObject, engine->newFunction(&Process::ctor)); diff --git a/src/lib/jsextensions/process.h b/src/lib/jsextensions/process.h index b2a99daa9..702513b96 100644 --- a/src/lib/jsextensions/process.h +++ b/src/lib/jsextensions/process.h @@ -42,13 +42,12 @@ QT_END_NAMESPACE namespace qbs { namespace Internal { +void initializeJsExtensionProcess(QScriptValue extensionObject); class Process : public QObject, public QScriptable { Q_OBJECT public: - static void init(QScriptValue extensionObject); - static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine); Process(QScriptContext *context); ~Process(); diff --git a/src/lib/jsextensions/textfile.cpp b/src/lib/jsextensions/textfile.cpp index ea42b55b9..794f5e4e9 100644 --- a/src/lib/jsextensions/textfile.cpp +++ b/src/lib/jsextensions/textfile.cpp @@ -39,7 +39,7 @@ namespace qbs { namespace Internal { -void TextFile::init(QScriptValue extensionObject) +void initializeJsExtensionTextFile(QScriptValue extensionObject) { QScriptEngine *engine = extensionObject.engine(); QScriptValue obj = engine->newQMetaObject(&TextFile::staticMetaObject, engine->newFunction(&TextFile::ctor)); diff --git a/src/lib/jsextensions/textfile.h b/src/lib/jsextensions/textfile.h index aac838091..2874f18bd 100644 --- a/src/lib/jsextensions/textfile.h +++ b/src/lib/jsextensions/textfile.h @@ -42,13 +42,13 @@ QT_END_NAMESPACE namespace qbs { namespace Internal { +void initializeJsExtensionTextFile(QScriptValue extensionObject); + class TextFile : public QObject, public QScriptable { Q_OBJECT Q_ENUMS(OpenMode) public: - static void init(QScriptValue extensionObject); - enum OpenMode { ReadOnly, WriteOnly, ReadWrite }; static QScriptValue ctor(QScriptContext *context, QScriptEngine *engine); TextFile(QScriptContext *context, const QString &file, OpenMode mode = ReadOnly, const QString &codec = QLatin1String("UTF8")); diff --git a/src/lib/language/evaluator.cpp b/src/lib/language/evaluator.cpp index 43a8580a8..117962fcc 100644 --- a/src/lib/language/evaluator.cpp +++ b/src/lib/language/evaluator.cpp @@ -33,6 +33,7 @@ #include "filecontext.h" #include "filetags.h" #include "item.h" +#include <jsextensions/jsextensions.h> #include <logging/translator.h> #include <tools/error.h> #include <tools/qbsassert.h> @@ -184,6 +185,7 @@ QScriptValue Evaluator::fileScope(const FileContextConstPtr &file) result.setProperty(QLatin1String("filePath"), file->filePath()); result.setProperty(QLatin1String("path"), file->dirPath()); m_scriptEngine->import(file->jsImports(), result, result); + JsExtensions::setupExtensions(file->jsExtensions(), result); return result; } diff --git a/src/lib/language/filecontext.h b/src/lib/language/filecontext.h index 3f4b96aeb..1d3d2ca5e 100644 --- a/src/lib/language/filecontext.h +++ b/src/lib/language/filecontext.h @@ -33,6 +33,8 @@ #include "item.h" #include "jsimports.h" +#include <QStringList> + namespace qbs { namespace Internal { @@ -48,11 +50,14 @@ public: QString filePath() const; QString dirPath() const; JsImports jsImports() const; + QStringList jsExtensions() const; + Item *idScope() const; private: QString m_filePath; JsImports m_jsImports; + QStringList m_jsExtensions; Item *m_idScope; }; @@ -66,6 +71,11 @@ inline JsImports FileContext::jsImports() const return m_jsImports; } +inline QStringList FileContext::jsExtensions() const +{ + return m_jsExtensions; +} + inline Item *FileContext::idScope() const { return m_idScope; diff --git a/src/lib/language/itemreaderastvisitor.cpp b/src/lib/language/itemreaderastvisitor.cpp index 24bfb3936..efb1171a2 100644 --- a/src/lib/language/itemreaderastvisitor.cpp +++ b/src/lib/language/itemreaderastvisitor.cpp @@ -32,6 +32,7 @@ #include "builtindeclarations.h" #include "identifiersearch.h" #include "itemreader.h" +#include <jsextensions/jsextensions.h> #include <parser/qmljsast_p.h> #include <tools/error.h> #include <tools/fileinfo.h> @@ -134,6 +135,23 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) toCodeLocation(import->importIdToken)); } } else { + if (importUri.count() == 2 && importUri.first() == QLatin1String("qbs")) { + const QString extensionName = importUri.last(); + if (JsExtensions::hasExtension(extensionName)) { + if (Q_UNLIKELY(!import->importId.isNull())) { + throw ErrorInfo(Tr::tr("Import of built-in extension '%1' " + "must not have 'as' specifier.").arg(extensionName)); + } + if (Q_UNLIKELY(m_file->m_jsExtensions.contains(extensionName))) { + m_reader->logger().printWarning(Tr::tr("Built-in extension '%1' already " + "imported.").arg(extensionName)); + } else { + m_file->m_jsExtensions << extensionName; + } + continue; + } + } + if (Q_UNLIKELY(import->importId.isNull())) { throw ErrorInfo(Tr::tr("Imports require 'as <Name>'"), toCodeLocation(import->importToken)); @@ -144,6 +162,10 @@ bool ItemReaderASTVisitor::visit(AST::UiImportList *uiImportList) throw ErrorInfo(Tr::tr("Can't import into the same name more than once."), toCodeLocation(import->importIdToken)); } + if (Q_UNLIKELY(JsExtensions::hasExtension(as))) { + throw ErrorInfo(Tr::tr("Cannot use the name of built-in extension '%1' in an 'as' " + "specifier.").arg(as)); + } importAsNames.insert(as); } diff --git a/src/lib/language/language.cpp b/src/lib/language/language.cpp index 8be684693..8711bd0c5 100644 --- a/src/lib/language/language.cpp +++ b/src/lib/language/language.cpp @@ -35,6 +35,7 @@ #include <buildgraph/productbuilddata.h> #include <buildgraph/projectbuilddata.h> #include <buildgraph/rulegraph.h> // TODO: Move to language? +#include <jsextensions/jsextensions.h> #include <logging/translator.h> #include <tools/hostosinfo.h> #include <tools/error.h> @@ -251,6 +252,7 @@ void ResolvedModule::load(PersistentPool &pool) setupBuildEnvironmentScript = pool.idLoadString(); setupRunEnvironmentScript = pool.idLoadString(); pool.stream() >> jsImports + >> jsExtensions >> setupBuildEnvironmentScript >> setupRunEnvironmentScript; } @@ -262,6 +264,7 @@ void ResolvedModule::store(PersistentPool &pool) const pool.storeString(setupBuildEnvironmentScript); pool.storeString(setupRunEnvironmentScript); pool.stream() << jsImports + << jsExtensions << setupBuildEnvironmentScript << setupRunEnvironmentScript; } @@ -285,6 +288,7 @@ void Rule::load(PersistentPool &pool) script = pool.idLoadS<PrepareScript>(); module = pool.idLoadS<ResolvedModule>(); pool.stream() >> jsImports + >> jsExtensions >> inputs >> usings >> explicitlyDependsOn @@ -298,6 +302,7 @@ void Rule::store(PersistentPool &pool) const pool.store(script); pool.store(module); pool.stream() << jsImports + << jsExtensions << inputs << usings << explicitlyDependsOn @@ -494,6 +499,7 @@ static QProcessEnvironment getProcessEnvironment(ScriptEngine *engine, EnvType e // handle imports engine->import(module->jsImports, scope, scope); + JsExtensions::setupExtensions(module->jsExtensions, scope); // expose properties of direct module dependencies QScriptValue scriptValue; diff --git a/src/lib/language/language.h b/src/lib/language/language.h index e1a549855..d142ba1bf 100644 --- a/src/lib/language/language.h +++ b/src/lib/language/language.h @@ -210,6 +210,7 @@ public: QString name; QStringList moduleDependencies; JsImports jsImports; + QStringList jsExtensions; QString setupBuildEnvironmentScript; QString setupRunEnvironmentScript; @@ -236,6 +237,7 @@ public: ResolvedModuleConstPtr module; JsImports jsImports; + QStringList jsExtensions; PrepareScriptConstPtr script; FileTags inputs; FileTags usings; @@ -268,6 +270,7 @@ public: QList<SourceArtifactPtr> outputs; PrepareScriptConstPtr transform; JsImports jsImports; + QStringList jsExtensions; private: ResolvedTransformer() {} diff --git a/src/lib/language/moduleloader.cpp b/src/lib/language/moduleloader.cpp index d8d0d48ce..aaa6e5c09 100644 --- a/src/lib/language/moduleloader.cpp +++ b/src/lib/language/moduleloader.cpp @@ -36,10 +36,6 @@ #include "item.h" #include "itemreader.h" #include "scriptengine.h" -#include <jsextensions/domxml.h> -#include <jsextensions/file.h> -#include <jsextensions/process.h> -#include <jsextensions/textfile.h> #include <language/language.h> #include <language/scriptengine.h> #include <logging/logger.h> @@ -820,10 +816,6 @@ void ModuleLoader::resolveProbe(Item *parent, Item *probe) } } QScriptValue scope = m_engine->newObject(); - File::init(scope); - Process::init(scope); - TextFile::init(scope); - DomXml::init(scope); m_engine->currentContext()->pushScope(m_evaluator->scriptValue(parent)); m_engine->currentContext()->pushScope(scope); m_engine->currentContext()->pushScope(m_evaluator->fileScope(configureScript->file())); diff --git a/src/lib/language/projectresolver.cpp b/src/lib/language/projectresolver.cpp index 2c67de70b..1b2c092ea 100644 --- a/src/lib/language/projectresolver.cpp +++ b/src/lib/language/projectresolver.cpp @@ -325,6 +325,7 @@ void ProjectResolver::resolveModule(const QStringList &moduleName, Item *item, // TODO: instead of jsImports, we need the file context for both setup scripts separately. // ATM the setup scripts must be in the first file of the inheritance chain. module->jsImports = item->file()->jsImports(); + module->jsExtensions = item->file()->jsExtensions(); foreach (const Item::Module &m, item->modules()) module->moduleDependencies += ModuleLoader::fullModuleName(m.name); @@ -501,6 +502,7 @@ void ProjectResolver::resolveRule(Item *item, ProjectContext *projectContext) } rule->jsImports = item->file()->jsImports(); + rule->jsExtensions = item->file()->jsExtensions(); rule->script = prepareScript; rule->multiplex = m_evaluator->boolValue(item, "multiplex", false); rule->inputs = m_evaluator->fileTagsValue(item, "inputs"); @@ -609,6 +611,7 @@ void ProjectResolver::resolveTransformer(Item *item, ProjectContext *projectCont ResolvedTransformer::Ptr rtrafo = ResolvedTransformer::create(); rtrafo->module = m_moduleContext ? m_moduleContext->module : projectContext->dummyModule; rtrafo->jsImports = item->file()->jsImports(); + rtrafo->jsExtensions = item->file()->jsExtensions(); rtrafo->inputs = m_evaluator->stringListValue(item, "inputs"); for (int i = 0; i < rtrafo->inputs.count(); ++i) rtrafo->inputs[i] = FileInfo::resolvePath(m_productContext->product->sourceDirectory, rtrafo->inputs.at(i)); diff --git a/src/lib/language/testdata/erroneous/reserved_name_in_import.qbs b/src/lib/language/testdata/erroneous/reserved_name_in_import.qbs new file mode 100644 index 000000000..3940109d0 --- /dev/null +++ b/src/lib/language/testdata/erroneous/reserved_name_in_import.qbs @@ -0,0 +1,4 @@ +import qbs +import "../idusagebase.qbs" as TextFile + +Product { } diff --git a/src/lib/language/tst_language.cpp b/src/lib/language/tst_language.cpp index cb9cc90ef..56fb75311 100644 --- a/src/lib/language/tst_language.cpp +++ b/src/lib/language/tst_language.cpp @@ -294,6 +294,8 @@ void TestLanguage::erroneousFiles_data() << "does not exist"; QTest::newRow("invalid_property_type") << "Unknown type 'nonsense' in property declaration."; + QTest::newRow("reserved_name_in_import") + << "Cannot use the name of built-in extension 'TextFile' in an 'as' specifier."; QTest::newRow("throw_in_property_binding") << "something is wrong"; } diff --git a/src/lib/lib.qbs b/src/lib/lib.qbs index 9e8bc27d8..69c11e709 100644 --- a/src/lib/lib.qbs +++ b/src/lib/lib.qbs @@ -126,6 +126,8 @@ Product { files: [ "file.cpp", "file.h", + "jsextensions.cpp", + "jsextensions.h", "moduleproperties.cpp", "moduleproperties.h", "process.cpp", diff --git a/src/lib/tools/persistence.cpp b/src/lib/tools/persistence.cpp index 0488d579b..d891b1d1e 100644 --- a/src/lib/tools/persistence.cpp +++ b/src/lib/tools/persistence.cpp @@ -40,7 +40,7 @@ namespace qbs { namespace Internal { -static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-42"; +static const char QBS_PERSISTENCE_MAGIC[] = "QBSPERSISTENCE-43"; PersistentPool::PersistentPool(const Logger &logger) : m_logger(logger) { diff --git a/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs b/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs index 96058f107..136e3e032 100644 --- a/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs +++ b/tests/auto/blackbox/testdata/dependenciesProperty/dependenciesProperty.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.TextFile import qbs.fileinfo as FileInfo Project { diff --git a/tests/auto/blackbox/testdata/productproperties/header.qbs b/tests/auto/blackbox/testdata/productproperties/header.qbs index 76e20eb83..51757b29e 100644 --- a/tests/auto/blackbox/testdata/productproperties/header.qbs +++ b/tests/auto/blackbox/testdata/productproperties/header.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.TextFile Product { name: "blubb_header" diff --git a/tests/auto/blackbox/testdata/qt5plugin/plugin.qbs b/tests/auto/blackbox/testdata/qt5plugin/plugin.qbs index eeced83b2..14e2c49df 100644 --- a/tests/auto/blackbox/testdata/qt5plugin/plugin.qbs +++ b/tests/auto/blackbox/testdata/qt5plugin/plugin.qbs @@ -1,4 +1,5 @@ import qbs.base +import qbs.File import qbs.fileinfo as FileInfo DynamicLibrary { diff --git a/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs b/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs index fa2654959..62d7f8fe1 100644 --- a/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs +++ b/tests/auto/blackbox/testdata/ruleConditions/modules/narfzort/narfzort.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.TextFile Module { property bool buildZort: true diff --git a/tests/auto/blackbox/testdata/trackFileTags/after/project.qbs b/tests/auto/blackbox/testdata/trackFileTags/after/project.qbs index 5d4dd9eb2..e770c6212 100644 --- a/tests/auto/blackbox/testdata/trackFileTags/after/project.qbs +++ b/tests/auto/blackbox/testdata/trackFileTags/after/project.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.TextFile Project { Product { diff --git a/tests/auto/blackbox/testdata/trackFileTags/before/project.qbs b/tests/auto/blackbox/testdata/trackFileTags/before/project.qbs index 9a19670cf..dbe4df6c3 100644 --- a/tests/auto/blackbox/testdata/trackFileTags/before/project.qbs +++ b/tests/auto/blackbox/testdata/trackFileTags/before/project.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.TextFile Project { Product { diff --git a/tests/manual/genmoc_cpp/moc_cpp.qbs b/tests/manual/genmoc_cpp/moc_cpp.qbs index e16955eab..ccbd70ba1 100644 --- a/tests/manual/genmoc_cpp/moc_cpp.qbs +++ b/tests/manual/genmoc_cpp/moc_cpp.qbs @@ -1,4 +1,5 @@ import qbs 1.0 +import qbs.TextFile import qbs.fileinfo as FileInfo Project { diff --git a/tests/manual/transformers/transformers.qbs b/tests/manual/transformers/transformers.qbs index 12aa66bc8..08444f975 100644 --- a/tests/manual/transformers/transformers.qbs +++ b/tests/manual/transformers/transformers.qbs @@ -1,4 +1,7 @@ import qbs 1.0 +import qbs.File +import qbs.TextFile +import qbs.Xml import qbs.fileinfo as FileInfo Project { |