diff options
| author | Joerg Bornemann <joerg.bornemann@digia.com> | 2013-09-24 12:22:48 +0200 |
|---|---|---|
| committer | Joerg Bornemann <joerg.bornemann@digia.com> | 2013-09-24 15:01:59 +0200 |
| commit | 543a38424a98bb72b8cf34bacbd3ff552a306776 (patch) | |
| tree | e6f4a9d2bf041dc007dff033a32b24ed2340504f /src/lib/buildgraph | |
| parent | 6a3f198e1a8beebc8cc1cf560016125efc60970b (diff) | |
| download | qbs-543a38424a98bb72b8cf34bacbd3ff552a306776.tar.gz | |
fix calling of prepare script function
The scope that contains inputs, outputs and friends was bound to the
function object, which is wrong when applying the function later on.
Instead, we're passing those variables as function arguments now.
Change-Id: I7ad7b6a742091fae889ed57b7c9cbceea4a2ead2
Reviewed-by: Christian Kandeler <christian.kandeler@digia.com>
Diffstat (limited to 'src/lib/buildgraph')
| -rw-r--r-- | src/lib/buildgraph/buildgraph.cpp | 10 | ||||
| -rw-r--r-- | src/lib/buildgraph/buildgraph.h | 2 | ||||
| -rw-r--r-- | src/lib/buildgraph/jscommandexecutor.cpp | 1 | ||||
| -rw-r--r-- | src/lib/buildgraph/projectbuilddata.cpp | 12 | ||||
| -rw-r--r-- | src/lib/buildgraph/rulesapplicator.cpp | 34 | ||||
| -rw-r--r-- | src/lib/buildgraph/rulesapplicator.h | 2 | ||||
| -rw-r--r-- | src/lib/buildgraph/transformer.cpp | 4 | ||||
| -rw-r--r-- | src/lib/buildgraph/transformer.h | 2 |
8 files changed, 45 insertions, 22 deletions
diff --git a/src/lib/buildgraph/buildgraph.cpp b/src/lib/buildgraph/buildgraph.cpp index d868d28b2..34a2eac4e 100644 --- a/src/lib/buildgraph/buildgraph.cpp +++ b/src/lib/buildgraph/buildgraph.cpp @@ -159,6 +159,13 @@ static void setupProductScriptValue(ScriptEngine *engine, QScriptValue &productS } } +void setupScriptEngineForFile(ScriptEngine *engine, const ResolvedFileContextConstPtr &fileContext, + QScriptValue targetObject) +{ + engine->import(fileContext->jsImports, targetObject, targetObject); + JsExtensions::setupExtensions(fileContext->jsExtensions, targetObject); +} + void setupScriptEngineForProduct(ScriptEngine *engine, const ResolvedProductConstPtr &product, const RuleConstPtr &rule, QScriptValue targetObject, ScriptPropertyObserver *observer) @@ -198,9 +205,6 @@ void setupScriptEngineForProduct(ScriptEngine *engine, const ResolvedProductCons // If the Rule is in a Module, set up the 'moduleName' property cache->productScriptValue.setProperty(QLatin1String("moduleName"), rule->module->name.isEmpty() ? QScriptValue() : rule->module->name); - - engine->import(rule->script->fileContext->jsImports, targetObject, targetObject); - JsExtensions::setupExtensions(rule->script->fileContext->jsExtensions, targetObject); } bool findPath(Artifact *u, Artifact *v, QList<Artifact*> &path) diff --git a/src/lib/buildgraph/buildgraph.h b/src/lib/buildgraph/buildgraph.h index fc2713a0a..4ac59fe07 100644 --- a/src/lib/buildgraph/buildgraph.h +++ b/src/lib/buildgraph/buildgraph.h @@ -72,6 +72,8 @@ bool safeConnect(Artifact *u, Artifact *v, const Logger &logger); void removeGeneratedArtifactFromDisk(Artifact *artifact, const Logger &logger); void disconnect(Artifact *u, Artifact *v, const Logger &logger); +void setupScriptEngineForFile(ScriptEngine *engine, const ResolvedFileContextConstPtr &fileContext, + QScriptValue targetObject); void setupScriptEngineForProduct(ScriptEngine *engine, const ResolvedProductConstPtr &product, const RuleConstPtr &rule, QScriptValue targetObject, ScriptPropertyObserver *observer = 0); diff --git a/src/lib/buildgraph/jscommandexecutor.cpp b/src/lib/buildgraph/jscommandexecutor.cpp index 24ffb7e6e..08b68409c 100644 --- a/src/lib/buildgraph/jscommandexecutor.cpp +++ b/src/lib/buildgraph/jscommandexecutor.cpp @@ -79,6 +79,7 @@ public slots: m_result.errorMessage.clear(); ScriptEngine * const scriptEngine = provideScriptEngine(); QScriptValue scope = scriptEngine->newObject(); + setupScriptEngineForFile(scriptEngine, transformer->rule->script->fileContext, scope); setupScriptEngineForProduct(scriptEngine, transformer->product(), transformer->rule, scope); transformer->setupInputs(scriptEngine, scope); transformer->setupOutputs(scriptEngine, scope); diff --git a/src/lib/buildgraph/projectbuilddata.cpp b/src/lib/buildgraph/projectbuilddata.cpp index aa39646db..e60278ea2 100644 --- a/src/lib/buildgraph/projectbuilddata.cpp +++ b/src/lib/buildgraph/projectbuilddata.cpp @@ -321,10 +321,14 @@ void BuildDataResolver::resolveProductBuildData(const ResolvedProductPtr &produc transformer->rule = rule; RulesEvaluationContext::Scope s(evalContext().data()); - setupScriptEngineForProduct(engine(), product, transformer->rule, scope()); - transformer->setupInputs(engine(), scope()); - transformer->setupOutputs(engine(), scope()); - transformer->createCommands(rtrafo->transform, evalContext()); + setupScriptEngineForFile(engine(), transformer->rule->script->fileContext, scope()); + QScriptValue prepareScriptContext = engine()->newObject(); + setupScriptEngineForProduct(engine(), product, transformer->rule, prepareScriptContext); + transformer->setupInputs(engine(), prepareScriptContext); + transformer->setupOutputs(engine(), prepareScriptContext); + transformer->createCommands(rtrafo->transform, evalContext(), + ScriptEngine::argumentList(transformer->rule->script->argumentNames, + prepareScriptContext)); if (Q_UNLIKELY(transformer->commands.isEmpty())) throw ErrorInfo(QString("There's a transformer without commands."), rtrafo->transform->location); } diff --git a/src/lib/buildgraph/rulesapplicator.cpp b/src/lib/buildgraph/rulesapplicator.cpp index d057c3cfb..70de2bc17 100644 --- a/src/lib/buildgraph/rulesapplicator.cpp +++ b/src/lib/buildgraph/rulesapplicator.cpp @@ -67,30 +67,35 @@ void RulesApplicator::applyAllRules() void RulesApplicator::applyRule(const RuleConstPtr &rule) { m_rule = rule; - QScriptValue scopeValue = scope(); - setupScriptEngineForProduct(engine(), m_product, m_rule, scopeValue, this); - Q_ASSERT_X(scope().property("product").strictlyEquals(engine()->evaluate("product")), - "BG", "Product object is not in current scope."); - m_productObjectId = scopeValue.property(QLatin1String("product")).objectId(); + QScriptValue prepareScriptContext = engine()->newObject(); + setupScriptEngineForFile(engine(), m_rule->script->fileContext, scope()); + setupScriptEngineForProduct(engine(), m_product, m_rule, prepareScriptContext, this); + m_productObjectId = prepareScriptContext.property(QLatin1String("product")).objectId(); ArtifactList inputArtifacts; foreach (const FileTag &fileTag, m_rule->inputs) inputArtifacts.unite(m_artifactsPerFileTag.value(fileTag)); if (m_rule->multiplex) { // apply the rule once for a set of inputs if (!inputArtifacts.isEmpty()) - doApply(inputArtifacts); + doApply(inputArtifacts, prepareScriptContext); } else { // apply the rule once for each input ArtifactList lst; foreach (Artifact * const inputArtifact, inputArtifacts) { setupScriptEngineForArtifact(inputArtifact); lst += inputArtifact; - doApply(lst); + doApply(lst, prepareScriptContext); lst.clear(); } } } -void RulesApplicator::doApply(const ArtifactList &inputArtifacts) +static void copyProperty(const QString &name, const QScriptValue &src, QScriptValue dst) +{ + dst.setProperty(name, src.property(name)); +} + +void RulesApplicator::doApply(const ArtifactList &inputArtifacts, + QScriptValue &prepareScriptContext) { evalContext()->checkForCancelation(); @@ -119,6 +124,8 @@ void RulesApplicator::doApply(const ArtifactList &inputArtifacts) m_transformer.clear(); // create the output artifacts from the set of input artifacts + copyProperty(QLatin1String("product"), prepareScriptContext, scope()); + copyProperty(QLatin1String("project"), prepareScriptContext, scope()); foreach (const RuleArtifactConstPtr &ruleArtifact, m_rule->artifacts) { Artifact * const outputArtifact = createOutputArtifact(ruleArtifact, inputArtifacts); outputArtifacts << outputArtifact; @@ -149,10 +156,12 @@ void RulesApplicator::doApply(const ArtifactList &inputArtifacts) -= outputArtifact; } - m_transformer->setupInputs(engine(), scope()); + m_transformer->setupInputs(engine(), prepareScriptContext); // change the transformer outputs according to the bindings in Artifact QScriptValue scriptValue; + if (!ruleArtifactArtifactMap.isEmpty()) + engine()->currentContext()->pushScope(prepareScriptContext); for (int i = ruleArtifactArtifactMap.count(); --i >= 0;) { const RuleArtifact *ra = ruleArtifactArtifactMap.at(i).first; if (ra->bindings.isEmpty()) @@ -180,9 +189,12 @@ void RulesApplicator::doApply(const ArtifactList &inputArtifacts) outputArtifactConfig.insert("modules", artifactModulesCfg); outputArtifact->properties->setValue(outputArtifactConfig); } + if (!ruleArtifactArtifactMap.isEmpty()) + engine()->currentContext()->popScope(); - m_transformer->setupOutputs(engine(), scope()); - m_transformer->createCommands(m_rule->script, evalContext()); + m_transformer->setupOutputs(engine(), prepareScriptContext); + m_transformer->createCommands(m_rule->script, evalContext(), + ScriptEngine::argumentList(m_rule->script->argumentNames, prepareScriptContext)); if (Q_UNLIKELY(m_transformer->commands.isEmpty())) throw ErrorInfo(QString("There's a rule without commands: %1.").arg(m_rule->toString()), m_rule->script->location); } diff --git a/src/lib/buildgraph/rulesapplicator.h b/src/lib/buildgraph/rulesapplicator.h index 9d7d75ff7..622391c5b 100644 --- a/src/lib/buildgraph/rulesapplicator.h +++ b/src/lib/buildgraph/rulesapplicator.h @@ -55,7 +55,7 @@ public: void applyRule(const RuleConstPtr &rule); private: - void doApply(const ArtifactList &inputArtifacts); + void doApply(const ArtifactList &inputArtifacts, QScriptValue &prepareScriptContext); void setupScriptEngineForArtifact(Artifact *artifact); Artifact *createOutputArtifact(const RuleArtifactConstPtr &ruleArtifact, const ArtifactList &inputArtifacts); diff --git a/src/lib/buildgraph/transformer.cpp b/src/lib/buildgraph/transformer.cpp index 4c61ac13d..13d98c284 100644 --- a/src/lib/buildgraph/transformer.cpp +++ b/src/lib/buildgraph/transformer.cpp @@ -143,7 +143,7 @@ static AbstractCommand *createCommandFromScriptValue(const QScriptValue &scriptV } void Transformer::createCommands(const ScriptFunctionConstPtr &script, - const RulesEvaluationContextPtr &evalContext) + const RulesEvaluationContextPtr &evalContext, const QScriptValueList &args) { ScriptEngine * const engine = evalContext->engine(); if (!script->scriptFunction.isValid() || script->scriptFunction.engine() != engine) { @@ -152,7 +152,7 @@ void Transformer::createCommands(const ScriptFunctionConstPtr &script, throw ErrorInfo(Tr::tr("Invalid prepare script."), script->location); } - QScriptValue scriptValue = script->scriptFunction.call(); + QScriptValue scriptValue = script->scriptFunction.call(QScriptValue(), args); propertiesRequestedFromProductInPrepareScript = engine->propertiesRequestedFromProduct(); propertiesRequestedFromArtifactInPrepareScript = engine->propertiesRequestedFromArtifact(); engine->clearPropertiesRequestedInPrepareScripts(); diff --git a/src/lib/buildgraph/transformer.h b/src/lib/buildgraph/transformer.h index f6b6c4904..35ace34d4 100644 --- a/src/lib/buildgraph/transformer.h +++ b/src/lib/buildgraph/transformer.h @@ -71,7 +71,7 @@ public: void setupInputs(QScriptEngine *scriptEngine, QScriptValue targetScriptValue); void setupOutputs(QScriptEngine *scriptEngine, QScriptValue targetScriptValue); void createCommands(const ScriptFunctionConstPtr &script, - const RulesEvaluationContextPtr &evalContext); + const RulesEvaluationContextPtr &evalContext, const QScriptValueList &args); private: Transformer(); |
