Skip to content

Commit 7ed51aa

Browse files
author
Caio Marcelo de Oliveira Filho
committed
QDeclarativeEnginePrivate: fix and encapsulate the usage of scopeChainValue
Reduce the places that we make a direct reference to the scopeChainValue (and the "-3" position) by providing a higher level function that gets the scopeNode of the Declarative Context that is in the current execution. This commit also fixes the offset of the wanted nodes in the scope chain. In the long term we still need to get rid of this scope chain direct manipulation if possible. Reviewed-by: Olivier Goffart
1 parent 96fb071 commit 7ed51aa

File tree

4 files changed

+30
-25
lines changed

4 files changed

+30
-25
lines changed

src/declarative/qml/qdeclarativeengine.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1262,9 +1262,8 @@ QScriptValue QDeclarativeEnginePrivate::qmlScriptObject(QObject* object,
12621262
*/
12631263
QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *ctxt)
12641264
{
1265-
QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1265+
QScriptValue scopeNode = getEvaluationContextScopeNode(ctxt);
12661266
Q_ASSERT(scopeNode.isValid());
1267-
Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
12681267
return contextClass->contextFromValue(scopeNode);
12691268
}
12701269

@@ -1274,12 +1273,24 @@ QDeclarativeContextData *QDeclarativeEnginePrivate::getContext(QScriptContext *c
12741273
*/
12751274
QUrl QDeclarativeEnginePrivate::getUrl(QScriptContext *ctxt)
12761275
{
1277-
QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(ctxt, -3);
1276+
QScriptValue scopeNode = getEvaluationContextScopeNode(ctxt);
12781277
Q_ASSERT(scopeNode.isValid());
1279-
Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
12801278
return contextClass->urlFromValue(scopeNode);
12811279
}
12821280

1281+
/*!
1282+
When valid, the returned QScriptValue contains the object that represents the
1283+
outer QDeclarativeContext of the current execution.
1284+
*/
1285+
QScriptValue QDeclarativeEnginePrivate::getEvaluationContextScopeNode(QScriptContext *context)
1286+
{
1287+
Q_ASSERT(context);
1288+
QScriptValue scopeNode = QScriptDeclarativeClass::scopeChainValue(context, -4);
1289+
if (scopeNode.isValid())
1290+
Q_ASSERT(QScriptDeclarativeClass::scriptClass(scopeNode) == contextClass);
1291+
return scopeNode;
1292+
}
1293+
12831294
QString QDeclarativeEnginePrivate::urlToLocalFileOrQrc(const QUrl& url)
12841295
{
12851296
if (url.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) == 0) {

src/declarative/qml/qdeclarativeengine_p.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeEnginePrivate : public QObjectPrivate
340340
static QDeclarativeEngine *get(QDeclarativeEnginePrivate *p) { return p->q_func(); }
341341
QDeclarativeContextData *getContext(QScriptContext *);
342342
QUrl getUrl(QScriptContext *);
343+
QScriptValue getEvaluationContextScopeNode(QScriptContext *);
343344

344345
static QString urlToLocalFileOrQrc(const QUrl& url);
345346

src/declarative/qml/qdeclarativeinclude.cpp

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,10 +57,11 @@ QDeclarativeInclude::QDeclarativeInclude(const QUrl &url,
5757
: QObject(engine), m_engine(engine), m_network(0), m_reply(0), m_http://github.com/url(url), m_redirectCount(0)
5858
{
5959
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
60-
m_context = ep->contextClass->contextFromValue(QScriptDeclarativeClass::scopeChainValue(ctxt, -3));
60+
m_context = ep->contextClass->contextFromValue(ep->getEvaluationContextScopeNode(ctxt));
61+
// ### Can/Should we assume m_context != 0? If so, why not use ep->getContext?
6162

62-
m_scope[0] = QScriptDeclarativeClass::scopeChainValue(ctxt, -4);
63-
m_scope[1] = QScriptDeclarativeClass::scopeChainValue(ctxt, -5);
63+
m_scope[0] = QScriptDeclarativeClass::scopeChainValue(ctxt, -5);
64+
m_scope[1] = QScriptDeclarativeClass::scopeChainValue(ctxt, -6);
6465

6566
m_scriptEngine = QDeclarativeEnginePrivate::getScriptEngine(engine);
6667
m_network = QDeclarativeScriptEngine::get(m_scriptEngine)->networkAccessManager();
@@ -181,8 +182,7 @@ QScriptValue QDeclarativeInclude::include(QScriptContext *ctxt, QScriptEngine *e
181182
return engine->undefinedValue();
182183

183184
QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine);
184-
185-
QUrl contextUrl = ep->contextClass->urlFromValue(QScriptDeclarativeClass::scopeChainValue(ctxt, -3));
185+
QUrl contextUrl = ep->contextClass->urlFromValue(ep->getEvaluationContextScopeNode(ctxt));
186186
if (contextUrl.isEmpty())
187187
return ctxt->throwError(QLatin1String("Qt.include(): Can only be called from JavaScript files"));
188188

@@ -216,12 +216,13 @@ QScriptValue QDeclarativeInclude::include(QScriptContext *ctxt, QScriptEngine *e
216216
QString code = QString::fromUtf8(data);
217217

218218
QDeclarativeContextData *context =
219-
ep->contextClass->contextFromValue(QScriptDeclarativeClass::scopeChainValue(ctxt, -3));
219+
ep->contextClass->contextFromValue(ep->getEvaluationContextScopeNode(ctxt));
220+
// ### Can/Should we assume context != 0, if so we can use ep->getContext()
220221

221222
QScriptContext *scriptContext = QScriptDeclarativeClass::pushCleanContext(engine);
222223
scriptContext->pushScope(ep->contextClass->newUrlContext(context, 0, urlString));
223224
scriptContext->pushScope(ep->globalClass->staticGlobalObject());
224-
QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -5);
225+
QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -6);
225226
scriptContext->pushScope(scope);
226227
scriptContext->setActivationObject(scope);
227228
QDeclarativeScriptParser::extractPragmas(code);
@@ -255,7 +256,7 @@ QScriptValue QDeclarativeInclude::worker_include(QScriptContext *ctxt, QScriptEn
255256
QString urlString = ctxt->argument(0).toString();
256257
QUrl url(ctxt->argument(0).toString());
257258
if (url.isRelative()) {
258-
QString contextUrl = QScriptDeclarativeClass::scopeChainValue(ctxt, -3).data().toString();
259+
QString contextUrl = QScriptDeclarativeClass::scopeChainValue(ctxt, -4).data().toString();
259260
Q_ASSERT(!contextUrl.isEmpty());
260261

261262
url = QUrl(contextUrl).resolved(url);
@@ -281,7 +282,7 @@ QScriptValue QDeclarativeInclude::worker_include(QScriptContext *ctxt, QScriptEn
281282
urlContext.setData(QScriptValue(engine, urlString));
282283
scriptContext->pushScope(urlContext);
283284

284-
QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -4);
285+
QScriptValue scope = QScriptDeclarativeClass::scopeChainValue(ctxt, -5);
285286
scriptContext->pushScope(scope);
286287
scriptContext->setActivationObject(scope);
287288
QDeclarativeScriptParser::extractPragmas(code);

src/declarative/qml/qdeclarativeobjectscriptclass.cpp

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,9 @@ QDeclarativeObjectScriptClass::queryProperty(QObject *obj, const Identifier &nam
177177

178178
if (!(hints & SkipAttachedProperties)) {
179179
if (!evalContext && context()) {
180-
// Global object, QScriptContext activation object, QDeclarativeContext object
181-
QScriptValue scopeNode = scopeChainValue(context(), -3);
182-
if (scopeNode.isValid()) {
183-
Q_ASSERT(scriptClass(scopeNode) == enginePrivate->contextClass);
184-
180+
QScriptValue scopeNode = enginePrivate->getEvaluationContextScopeNode(context());
181+
if (scopeNode.isValid())
185182
evalContext = enginePrivate->contextClass->contextFromValue(scopeNode);
186-
}
187183
}
188184

189185
if (evalContext && evalContext->imports) {
@@ -351,13 +347,9 @@ void QDeclarativeObjectScriptClass::setProperty(QObject *obj,
351347
QDeclarativeEnginePrivate *enginePriv = QDeclarativeEnginePrivate::get(engine);
352348

353349
if (!evalContext) {
354-
// Global object, QScriptContext activation object, QDeclarativeContext object
355-
QScriptValue scopeNode = scopeChainValue(context, -3);
356-
if (scopeNode.isValid()) {
357-
Q_ASSERT(scriptClass(scopeNode) == enginePriv->contextClass);
358-
350+
QScriptValue scopeNode = enginePriv->getEvaluationContextScopeNode(context);
351+
if (scopeNode.isValid())
359352
evalContext = enginePriv->contextClass->contextFromValue(scopeNode);
360-
}
361353
}
362354

363355
QDeclarativeBinding *newBinding = 0;

0 commit comments

Comments
 (0)