diff options
Diffstat (limited to 'src/qml/compiler/qqmlirbuilder.cpp')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 126 |
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); |