aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler/qqmlirbuilder.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/compiler/qqmlirbuilder.cpp')
-rw-r--r--src/qml/compiler/qqmlirbuilder.cpp126
1 files changed, 79 insertions, 47 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp
index 791355a668..eaf0e72296 100644
--- a/src/qml/compiler/qqmlirbuilder.cpp
+++ b/src/qml/compiler/qqmlirbuilder.cpp
@@ -1,31 +1,37 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:LGPL$
** 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 The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/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 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -244,8 +250,8 @@ void Document::collectTypeReferences()
void Document::removeScriptPragmas(QString &script)
{
- const QString pragma(QLatin1String("pragma"));
- const QString library(QLatin1String("library"));
+ const QLatin1String pragma("pragma");
+ const QLatin1String library("library");
QQmlJS::Lexer l(0);
l.setCode(script, 0);
@@ -263,7 +269,7 @@ void Document::removeScriptPragmas(QString &script)
if (token != QQmlJSGrammar::T_PRAGMA ||
l.tokenStartLine() != startLine ||
- script.mid(l.tokenOffset(), l.tokenLength()) != pragma)
+ script.midRef(l.tokenOffset(), l.tokenLength()) != pragma)
return;
token = l.lex();
@@ -272,7 +278,7 @@ void Document::removeScriptPragmas(QString &script)
l.tokenStartLine() != startLine)
return;
- QString pragmaValue = script.mid(l.tokenOffset(), l.tokenLength());
+ const QStringRef pragmaValue = script.midRef(l.tokenOffset(), l.tokenLength());
int endOffset = l.tokenLength() + l.tokenOffset();
token = l.lex();
@@ -339,6 +345,7 @@ IRBuilder::IRBuilder(const QSet<QString> &illegalNames)
: illegalNames(illegalNames)
, _object(0)
, _propertyDeclaration(0)
+ , pool(0)
, jsGenerator(0)
{
}
@@ -404,7 +411,7 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen
bool IRBuilder::isSignalPropertyName(const QString &name)
{
if (name.length() < 3) return false;
- if (!name.startsWith(QStringLiteral("on"))) return false;
+ if (!name.startsWith(QLatin1String("on"))) return false;
int ns = name.length();
for (int i = 2; i < ns; ++i) {
const QChar curr = name.at(i);
@@ -1054,7 +1061,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Sta
Object *object = 0;
if (!resolveQualifiedId(&name, &object))
return;
- if (_object == object && name->name == QStringLiteral("id")) {
+ if (_object == object && name->name == QLatin1String("id")) {
setId(name->identifierToken, value);
return;
}
@@ -1090,7 +1097,7 @@ void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLo
void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment)
{
- if (stringAt(propertyNameIndex) == QStringLiteral("id")) {
+ if (stringAt(propertyNameIndex) == QLatin1String("id")) {
recordError(nameLocation, tr("Invalid component id specification"));
return;
}
@@ -1185,7 +1192,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O
{
QQmlJS::AST::UiQualifiedId *qualifiedIdElement = *nameToResolve;
- if (qualifiedIdElement->name == QStringLiteral("id") && qualifiedIdElement->next)
+ if (qualifiedIdElement->name == QLatin1String("id") && qualifiedIdElement->next)
COMPILE_EXCEPTION(qualifiedIdElement->identifierToken, tr( "Invalid use of id property"));
// If it's a namespace, prepend the qualifier and we'll resolve it later to the correct type.
@@ -1582,7 +1589,9 @@ enum MetaObjectResolverFlags {
static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlPropertyCache *metaObject);
-static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::MemberExpressionResolver *resolver, QV4::IR::Member *member)
+static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine,
+ const QV4::IR::MemberExpressionResolver *resolver,
+ QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
@@ -1593,7 +1602,6 @@ static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::Membe
int value = type->enumValue(qmlEngine, *member->name, &ok);
if (ok) {
member->setEnumValue(value);
- resolver->clear();
return QV4::IR::SInt32Type;
}
}
@@ -1604,25 +1612,30 @@ static QV4::IR::Type resolveQmlType(QQmlEnginePrivate *qmlEngine, QV4::IR::Membe
tdata->release(); // Decrease the reference count added from QQmlTypeLoader::getType()
// When a singleton tries to reference itself, it may not be complete yet.
if (tdata->isComplete()) {
- initMetaObjectResolver(resolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId));
- resolver->flags |= AllPropertiesAreFinal;
- return resolver->resolveMember(qmlEngine, resolver, member);
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, qmlEngine->propertyCacheForType(tdata->compiledData()->metaTypeId));
+ newResolver->flags |= AllPropertiesAreFinal;
+ return newResolver->resolveMember(qmlEngine, newResolver, member);
}
} else if (type->isSingleton()) {
const QMetaObject *singletonMeta = type->singletonInstanceInfo()->instanceMetaObject;
if (singletonMeta) { // QJSValue-based singletons cannot be accelerated
- initMetaObjectResolver(resolver, qmlEngine->cache(singletonMeta));
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, qmlEngine->cache(singletonMeta));
member->kind = QV4::IR::Member::MemberOfSingletonObject;
- return resolver->resolveMember(qmlEngine, resolver, member);
+ return newResolver->resolveMember(qmlEngine, newResolver, member);
}
} else if (const QMetaObject *attachedMeta = type->attachedPropertiesType(qmlEngine)) {
QQmlPropertyCache *cache = qmlEngine->cache(attachedMeta);
- initMetaObjectResolver(resolver, cache);
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, cache);
member->setAttachedPropertiesId(type->attachedPropertiesId(qmlEngine));
- return resolver->resolveMember(qmlEngine, resolver, member);
+ return newResolver->resolveMember(qmlEngine, newResolver, member);
}
- resolver->clear();
return result;
}
@@ -1636,7 +1649,9 @@ static void initQmlTypeResolver(QV4::IR::MemberExpressionResolver *resolver, QQm
resolver->flags = 0;
}
-static QV4::IR::Type resolveImportNamespace(QQmlEnginePrivate *, QV4::IR::MemberExpressionResolver *resolver, QV4::IR::Member *member)
+static QV4::IR::DiscoveredType resolveImportNamespace(
+ QQmlEnginePrivate *, const QV4::IR::MemberExpressionResolver *resolver,
+ QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
QQmlTypeNameCache *typeNamespace = static_cast<QQmlTypeNameCache*>(resolver->extraData);
@@ -1653,19 +1668,21 @@ static QV4::IR::Type resolveImportNamespace(QQmlEnginePrivate *, QV4::IR::Member
// through the singleton getter in the run-time. Until then we
// can't accelerate access :(
if (!r.type->isSingleton()) {
- initQmlTypeResolver(resolver, r.type);
- return QV4::IR::QObjectType;
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initQmlTypeResolver(newResolver, r.type);
+ return QV4::IR::DiscoveredType(newResolver);
}
} else {
Q_ASSERT(false); // How can this happen?
}
}
- resolver->clear();
return result;
}
-static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlTypeNameCache *imports, const void *importNamespace)
+static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resolver,
+ QQmlTypeNameCache *imports, const void *importNamespace)
{
resolver->resolveMember = &resolveImportNamespace;
resolver->data = const_cast<void*>(importNamespace);
@@ -1673,7 +1690,9 @@ static void initImportNamespaceResolver(QV4::IR::MemberExpressionResolver *resol
resolver->flags = 0;
}
-static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4::IR::MemberExpressionResolver *resolver, QV4::IR::Member *member)
+static QV4::IR::DiscoveredType resolveMetaObjectProperty(
+ QQmlEnginePrivate *qmlEngine, const QV4::IR::MemberExpressionResolver *resolver,
+ QV4::IR::Member *member)
{
QV4::IR::Type result = QV4::IR::VarType;
QQmlPropertyCache *metaObject = static_cast<QQmlPropertyCache*>(resolver->data);
@@ -1687,7 +1706,6 @@ static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4
int value = metaEnum.keyToValue(enumName.constData(), &ok);
if (ok) {
member->setEnumValue(value);
- resolver->clear();
return QV4::IR::SInt32Type;
}
}
@@ -1732,21 +1750,25 @@ static QV4::IR::Type resolveMetaObjectProperty(QQmlEnginePrivate *qmlEngine, QV4
default:
if (property->isQObject()) {
if (QQmlPropertyCache *cache = qmlEngine->propertyCacheForType(property->propType)) {
- initMetaObjectResolver(resolver, cache);
- return QV4::IR::QObjectType;
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, cache);
+ return QV4::IR::DiscoveredType(newResolver);
}
} else if (const QMetaObject *valueTypeMetaObject = QQmlValueTypeFactory::metaObjectForMetaType(property->propType)) {
if (QQmlPropertyCache *cache = qmlEngine->cache(valueTypeMetaObject)) {
- initMetaObjectResolver(resolver, cache);
- resolver->flags |= ResolveTypeInformationOnly;
- return QV4::IR::QObjectType;
+ auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>();
+ newResolver->owner = resolver->owner;
+ initMetaObjectResolver(newResolver, cache);
+ newResolver->flags |= ResolveTypeInformationOnly;
+ return QV4::IR::DiscoveredType(newResolver);
}
}
break;
}
}
}
- resolver->clear();
+
return result;
}
@@ -1768,7 +1790,12 @@ void JSCodeGen::beginFunctionBodyHook()
#ifndef V4_BOOTSTRAP
QV4::IR::Temp *temp = _block->TEMP(_qmlContextTemp);
- move(temp, _block->NAME(QV4::IR::Name::builtin_qml_context, 0, 0));
+ temp->type = QV4::IR::QObjectType;
+ temp->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ initMetaObjectResolver(temp->memberResolver, _scopeObject);
+ auto name = _block->NAME(QV4::IR::Name::builtin_qml_context, 0, 0);
+ name->type = temp->type;
+ move(temp, name);
move(_block->TEMP(_importedScriptsTemp), _block->NAME(QV4::IR::Name::builtin_qml_imported_scripts_object, 0, 0));
#endif
@@ -1802,6 +1829,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
result = _block->TEMP(result->index);
if (mapping.type) {
result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ result->memberResolver->owner = _function;
initMetaObjectResolver(result->memberResolver, mapping.type);
result->memberResolver->flags |= AllPropertiesAreFinal;
}
@@ -1824,6 +1852,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
result = _block->TEMP(result->index);
result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ result->memberResolver->owner = _function;
initQmlTypeResolver(result->memberResolver, r.type);
return result;
} else {
@@ -1832,6 +1861,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
namespaceName->freeOfSideEffects = true;
QV4::IR::Temp *result = _block->TEMP(_block->newTemp());
result->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ result->memberResolver->owner = _function;
initImportNamespaceResolver(result->memberResolver, imports, r.importNamespace);
_block->MOVE(result, namespaceName);
@@ -1848,6 +1878,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
if (pd) {
QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ base->memberResolver->owner = _function;
initMetaObjectResolver(base->memberResolver, _scopeObject);
return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlScopeObject);
}
@@ -1861,6 +1892,7 @@ QV4::IR::Expr *JSCodeGen::fallbackNameLookup(const QString &name, int line, int
if (pd) {
QV4::IR::Temp *base = _block->TEMP(_qmlContextTemp);
base->memberResolver = _function->New<QV4::IR::MemberExpressionResolver>();
+ base->memberResolver->owner = _function;
initMetaObjectResolver(base->memberResolver, _contextObject);
return _block->MEMBER(base, _function->newString(name), pd, QV4::IR::Member::MemberOfQmlContextObject);
}
@@ -1911,7 +1943,7 @@ QQmlPropertyData *PropertyResolver::signal(const QString &name, bool *notInRevis
return d;
}
- if (name.endsWith(QStringLiteral("Changed"))) {
+ if (name.endsWith(QLatin1String("Changed"))) {
QString propName = name.mid(0, name.length() - static_cast<int>(strlen("Changed")));
d = property(propName, notInRevision);