diff options
Diffstat (limited to 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qqmlirbuilder.cpp | 202 | ||||
-rw-r--r-- | src/qml/compiler/qqmlirbuilder_p.h | 80 | ||||
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4bytecodegenerator_p.h | 4 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 43 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 12 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilercontext.cpp | 5 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilercontext_p.h | 12 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions.cpp | 6 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilerscanfunctions_p.h | 2 |
10 files changed, 286 insertions, 82 deletions
diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 665d2633a7..89f99e21cd 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -64,6 +64,33 @@ using namespace QQmlJS; return false; \ } +void Object::simplifyRequiredProperties() { + // if a property of the current object was marked as required + // do not store that information in the ExtraData + // but rather mark the property as required + QSet<int> required; + for (auto it = this->requiredPropertyExtraDataBegin(); it != this->requiredPropertyExtraDataEnd(); ++it) + required.insert(it->nameIndex); + if (required.isEmpty()) + return; + for (auto it = this->propertiesBegin(); it != this->propertiesEnd(); ++it) { + auto requiredIt = required.find(it->nameIndex); + if (requiredIt != required.end()) { + it->isRequired = true; + required.erase(requiredIt); + } + } + QmlIR::RequiredPropertyExtraData *prev = nullptr; + auto current = this->requiredPropertyExtraDatas->first; + while (current) { + if (required.contains(current->nameIndex)) + prev = current; + else + requiredPropertyExtraDatas->unlink(prev, current); + current = current->next; + } +} + bool Parameter::init(QV4::Compiler::JSUnitGenerator *stringGenerator, const QString ¶meterName, const QString &typeName) { @@ -142,7 +169,7 @@ QV4::CompiledData::BuiltinType Parameter::stringToBuiltinType(const QString &typ return QV4::CompiledData::BuiltinType::InvalidBuiltin; } -void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &loc) +void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::SourceLocation &loc) { inheritedTypeNameIndex = typeNameIndex; @@ -161,10 +188,12 @@ void Object::init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, cons bindings = pool->New<PoolList<Binding> >(); functions = pool->New<PoolList<Function> >(); functionsAndExpressions = pool->New<PoolList<CompiledFunctionOrExpression> >(); + inlineComponents = pool->New<PoolList<InlineComponent>>(); + requiredPropertyExtraDatas = pool->New<PoolList<RequiredPropertyExtraData>>(); declarationsOverride = nullptr; } -QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation) +QString IRBuilder::sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::SourceLocation *errorLocation) { QSet<int> functionNames; for (auto functionit = obj->functionsBegin(); functionit != obj->functionsEnd(); ++functionit) { @@ -220,7 +249,7 @@ QString Object::appendSignal(Signal *signal) return QString(); // no error } -QString Object::appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation) +QString Object::appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation) { Object *target = declarationsOverride; if (!target) @@ -244,15 +273,17 @@ QString Object::appendProperty(Property *prop, const QString &propertyName, bool return QString(); // no error } -QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation) +QString Object::appendAlias(Alias *alias, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation) { Object *target = declarationsOverride; if (!target) target = this; - for (Alias *p = target->aliases->first; p; p = p->next) - if (p->nameIndex == alias->nameIndex) - return tr("Duplicate alias name"); + auto aliasWithSameName = std::find_if(target->aliases->begin(), target->aliases->end(), [&alias](const Alias &targetAlias){ + return targetAlias.nameIndex == alias->nameIndex; + }); + if (aliasWithSameName != target->aliases->end()) + return tr("Duplicate alias name"); if (aliasName.constData()->isUpper()) return tr("Alias names cannot begin with an upper case letter"); @@ -279,6 +310,16 @@ void Object::appendFunction(QmlIR::Function *f) target->functions->append(f); } +void Object::appendInlineComponent(InlineComponent *ic) +{ + inlineComponents->append(ic); +} + +void Object::appendRequiredPropertyExtraData(RequiredPropertyExtraData *extraData) +{ + requiredPropertyExtraDatas->append(extraData); +} + QString Object::appendBinding(Binding *b, bool isListBinding) { const bool bindingToDefaultProperty = (b->propertyNameIndex == quint32(0)); @@ -317,8 +358,8 @@ QString Object::bindingAsString(Document *doc, int scriptIndex) const QQmlJS::AST::Node *node = foe->node; if (QQmlJS::AST::ExpressionStatement *exprStmt = QQmlJS::AST::cast<QQmlJS::AST::ExpressionStatement *>(node)) node = exprStmt->expression; - QQmlJS::AST::SourceLocation start = node->firstSourceLocation(); - QQmlJS::AST::SourceLocation end = node->lastSourceLocation(); + QQmlJS::SourceLocation start = node->firstSourceLocation(); + QQmlJS::SourceLocation end = node->lastSourceLocation(); return doc->code.mid(start.offset, end.offset + end.length - start.offset); } @@ -401,7 +442,7 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen // Extract errors from the parser for (const QQmlJS::DiagnosticMessage &m : diagnosticMessages) { if (m.isWarning()) { - qWarning("%s:%d : %s", qPrintable(url), m.line, qPrintable(m.message)); + qWarning("%s:%d : %s", qPrintable(url), m.loc.startLine, qPrintable(m.message)); continue; } @@ -429,7 +470,7 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen accept(program->headers); if (program->members->next) { - QQmlJS::AST::SourceLocation loc = program->members->next->firstSourceLocation(); + QQmlJS::SourceLocation loc = program->members->next->firstSourceLocation(); recordError(loc, QCoreApplication::translate("QQmlParser", "Unexpected object definition")); return false; } @@ -444,6 +485,10 @@ bool IRBuilder::generateFromQml(const QString &code, const QString &url, Documen qSwap(_imports, output->imports); qSwap(_pragmas, output->pragmas); qSwap(_objects, output->objects); + + for (auto object: output->objects) + object->simplifyRequiredProperties(); + return errors.isEmpty(); } @@ -490,7 +535,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiObjectDefinition *node) int idx = 0; if (!defineQMLObject(&idx, node)) return false; - const QQmlJS::AST::SourceLocation nameLocation = node->qualifiedTypeNameId->identifierToken; + const QQmlJS::SourceLocation nameLocation = node->qualifiedTypeNameId->identifierToken; appendBinding(nameLocation, nameLocation, emptyStringIndex, idx); } else { int idx = 0; @@ -501,6 +546,39 @@ bool IRBuilder::visit(QQmlJS::AST::UiObjectDefinition *node) return false; } +bool IRBuilder::visit(QQmlJS::AST::UiInlineComponent *ast) +{ + int idx = -1; + if (insideInlineComponent) { + recordError(ast->firstSourceLocation(), QLatin1String("Nested inline components are not supported")); + return false; + } + if (inlineComponentsNames.contains(ast->name.toString())) { + recordError(ast->firstSourceLocation(), QLatin1String("Inline component names must be unique per file")); + return false; + } else { + inlineComponentsNames.insert(ast->name.toString()); + } + { + QScopedValueRollback<bool> rollBack {insideInlineComponent, true}; + if (!defineQMLObject(&idx, ast->component)) + return false; + } + Q_ASSERT(idx > 0); + Object* definedObject = _objects.at(idx); + definedObject->flags |= QV4::CompiledData::Object::IsInlineComponentRoot; + definedObject->flags |= QV4::CompiledData::Object::InPartOfInlineComponent; + definedObject->isInlineComponent = true; + auto inlineComponent = New<InlineComponent>(); + inlineComponent->nameIndex = registerString(ast->name.toString()); + inlineComponent->objectIndex = idx; + auto location = ast->firstSourceLocation(); + inlineComponent->location.line = location.startLine; + inlineComponent->location.column = location.startColumn; + _object->appendInlineComponent(inlineComponent); + return false; +} + bool IRBuilder::visit(QQmlJS::AST::UiObjectBinding *node) { int idx = 0; @@ -518,7 +596,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiScriptBinding *node) bool IRBuilder::visit(QQmlJS::AST::UiArrayBinding *node) { - const QQmlJS::AST::SourceLocation qualifiedNameLocation = node->qualifiedId->identifierToken; + const QQmlJS::SourceLocation qualifiedNameLocation = node->qualifiedId->identifierToken; Object *object = nullptr; QQmlJS::AST::UiQualifiedId *name = node->qualifiedId; if (!resolveQualifiedId(&name, &object)) @@ -583,7 +661,7 @@ void IRBuilder::accept(QQmlJS::AST::Node *node) QQmlJS::AST::Node::accept(node, this); } -bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride) +bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride) { if (QQmlJS::AST::UiQualifiedId *lastName = qualifiedTypeNameId) { while (lastName->next) @@ -595,12 +673,16 @@ bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qu } Object *obj = New<Object>(); + _objects.append(obj); *objectIndex = _objects.size() - 1; qSwap(_object, obj); _object->init(pool, registerString(asString(qualifiedTypeNameId)), emptyStringIndex, location); _object->declarationsOverride = declarationsOverride; + if (insideInlineComponent) { + _object->flags |= QV4::CompiledData::Object::InPartOfInlineComponent; + } // A new object is also a boundary for property declarations. Property *declaration = nullptr; @@ -615,7 +697,7 @@ bool IRBuilder::defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qu if (!errors.isEmpty()) return false; - QQmlJS::AST::SourceLocation loc; + QQmlJS::SourceLocation loc; QString error = sanityCheckFunctionNames(obj, illegalNames, &loc); if (!error.isEmpty()) { recordError(loc, error); @@ -792,10 +874,10 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) { if (node->type == QQmlJS::AST::UiPublicMember::Signal) { Signal *signal = New<Signal>(); - QString signalName = node->name.toString(); + const QString signalName = node->name.toString(); signal->nameIndex = registerString(signalName); - QQmlJS::AST::SourceLocation loc = node->typeToken; + QQmlJS::SourceLocation loc = node->typeToken; signal->location.line = loc.startLine; signal->location.column = loc.startColumn; @@ -821,8 +903,14 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) p = p->next; } - if (signalName.at(0).isUpper()) - COMPILE_EXCEPTION(node->identifierToken, tr("Signal names cannot begin with an upper case letter")); + for (const QChar &ch : signalName) { + if (ch.isLower()) + break; + if (ch.isUpper()) { + COMPILE_EXCEPTION(node->identifierToken, + tr("Signal names cannot begin with an upper case letter")); + } + } if (illegalNames.contains(signalName)) COMPILE_EXCEPTION(node->identifierToken, tr("Illegal signal name")); @@ -841,6 +929,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) Property *property = New<Property>(); property->isReadOnly = node->isReadonlyMember; + property->isRequired = node->isRequired; QV4::CompiledData::BuiltinType builtinPropertyType = Parameter::stringToBuiltinType(memberType); bool typeFound = builtinPropertyType != QV4::CompiledData::BuiltinType::InvalidBuiltin; @@ -871,11 +960,11 @@ bool IRBuilder::visit(QQmlJS::AST::UiPublicMember *node) const QString propName = name.toString(); property->nameIndex = registerString(propName); - QQmlJS::AST::SourceLocation loc = node->firstSourceLocation(); + QQmlJS::SourceLocation loc = node->firstSourceLocation(); property->location.line = loc.startLine; property->location.column = loc.startColumn; - QQmlJS::AST::SourceLocation errorLocation; + QQmlJS::SourceLocation errorLocation; QString error; if (illegalNames.contains(propName)) @@ -916,7 +1005,7 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node) const int index = _object->functionsAndExpressions->append(foe); Function *f = New<Function>(); - QQmlJS::AST::SourceLocation loc = funDecl->identifierToken; + QQmlJS::SourceLocation loc = funDecl->identifierToken; f->location.line = loc.startLine; f->location.column = loc.startColumn; f->index = index; @@ -942,6 +1031,14 @@ bool IRBuilder::visit(QQmlJS::AST::UiSourceElement *node) return false; } +bool IRBuilder::visit(AST::UiRequired *ast) +{ + auto extraData = New<RequiredPropertyExtraData>(); + extraData->nameIndex = registerString(ast->name.toString()); + _object->appendRequiredPropertyExtraData(extraData); + return false; +} + QString IRBuilder::asString(QQmlJS::AST::UiQualifiedId *node) { QString s; @@ -982,14 +1079,14 @@ void IRBuilder::extractVersion(const QStringRef &string, int *maj, int *min) } } -QStringRef IRBuilder::textRefAt(const QQmlJS::AST::SourceLocation &first, const QQmlJS::AST::SourceLocation &last) const +QStringRef IRBuilder::textRefAt(const QQmlJS::SourceLocation &first, const QQmlJS::SourceLocation &last) const { return QStringRef(&sourceCode, first.offset, last.offset + last.length - first.offset); } void IRBuilder::setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, QQmlJS::AST::Node *parentNode) { - QQmlJS::AST::SourceLocation loc = statement->firstSourceLocation(); + QQmlJS::SourceLocation loc = statement->firstSourceLocation(); binding->valueLocation.line = loc.startLine; binding->valueLocation.column = loc.startColumn; binding->type = QV4::CompiledData::Binding::Type_Invalid; @@ -1166,7 +1263,7 @@ void IRBuilder::tryGeneratingTranslationBinding(const QStringRef &base, AST::Arg void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode) { - const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken; + const QQmlJS::SourceLocation qualifiedNameLocation = name->identifierToken; Object *object = nullptr; if (!resolveQualifiedId(&name, &object)) return; @@ -1181,7 +1278,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Sta void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment) { - const QQmlJS::AST::SourceLocation qualifiedNameLocation = name->identifierToken; + const QQmlJS::SourceLocation qualifiedNameLocation = name->identifierToken; Object *object = nullptr; if (!resolveQualifiedId(&name, &object, isOnAssignment)) return; @@ -1190,7 +1287,7 @@ void IRBuilder::appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, qSwap(_object, object); } -void IRBuilder::appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, +void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode) { Binding *binding = New<Binding>(); @@ -1206,7 +1303,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) +void IRBuilder::appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem, bool isOnAssignment) { if (stringAt(propertyNameIndex) == QLatin1String("id")) { recordError(nameLocation, tr("Invalid component id specification")); @@ -1255,7 +1352,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) const QString propName = node->name.toString(); alias->nameIndex = registerString(propName); - QQmlJS::AST::SourceLocation loc = node->firstSourceLocation(); + QQmlJS::SourceLocation loc = node->firstSourceLocation(); alias->location.line = loc.startLine; alias->location.column = loc.startColumn; @@ -1264,7 +1361,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) if (!node->statement && !node->binding) COMPILE_EXCEPTION(loc, tr("No property alias location")); - QQmlJS::AST::SourceLocation rhsLoc; + QQmlJS::SourceLocation rhsLoc; if (node->binding) rhsLoc = node->binding->firstSourceLocation(); else if (node->statement) @@ -1299,7 +1396,7 @@ bool IRBuilder::appendAlias(QQmlJS::AST::UiPublicMember *node) propertyValue += QLatin1Char('.') + aliasReference.at(2); alias->propertyNameIndex = registerString(propertyValue); - QQmlJS::AST::SourceLocation errorLocation; + QQmlJS::SourceLocation errorLocation; QString error; if (illegalNames.contains(propName)) @@ -1325,9 +1422,9 @@ Object *IRBuilder::bindingsTarget() const return _object; } -bool IRBuilder::setId(const QQmlJS::AST::SourceLocation &idLocation, QQmlJS::AST::Statement *value) +bool IRBuilder::setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value) { - QQmlJS::AST::SourceLocation loc = value->firstSourceLocation(); + QQmlJS::SourceLocation loc = value->firstSourceLocation(); QStringRef str; QQmlJS::AST::Node *node = value; @@ -1429,7 +1526,7 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O binding->type = QV4::CompiledData::Binding::Type_GroupProperty; int objIndex = 0; - if (!defineQMLObject(&objIndex, nullptr, QQmlJS::AST::SourceLocation(), nullptr, nullptr)) + if (!defineQMLObject(&objIndex, nullptr, QQmlJS::SourceLocation(), nullptr, nullptr)) return false; binding->value.objectIndex = objIndex; @@ -1452,11 +1549,10 @@ bool IRBuilder::resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, O return true; } -void IRBuilder::recordError(const QQmlJS::AST::SourceLocation &location, const QString &description) +void IRBuilder::recordError(const QQmlJS::SourceLocation &location, const QString &description) { QQmlJS::DiagnosticMessage error; - error.line = location.startLine; - error.column = location.startColumn; + error.loc = location; error.message = description; errors << error; } @@ -1544,7 +1640,7 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen uint nextOffset = objectOffset + objectOffsetTableSize; for (Object *o : qAsConst(output.objects)) { objectOffsets.insert(o, nextOffset); - nextOffset += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.size()); + nextOffset += QV4::CompiledData::Object::calculateSizeExcludingSignalsAndEnums(o->functionCount(), o->propertyCount(), o->aliasCount(), o->enumCount(), o->signalCount(), o->bindingCount(), o->namedObjectsInComponent.size(), o->inlineComponentCount(), o->requiredPropertyExtraDataCount()); int signalTableSize = 0; for (const Signal *s = o->firstSignal(); s; s = s->next) @@ -1623,6 +1719,14 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen objectToWrite->offsetToNamedObjectsInComponent = nextOffset; nextOffset += objectToWrite->nNamedObjectsInComponent * sizeof(quint32); + objectToWrite->nInlineComponents = o->inlineComponentCount(); + objectToWrite->offsetToInlineComponents = nextOffset; + nextOffset += objectToWrite->nInlineComponents * sizeof (QV4::CompiledData::InlineComponent); + + objectToWrite->nRequiredPropertyExtraData = o->requiredPropertyExtraDataCount(); + objectToWrite->offsetToRequiredPropertyExtraData = nextOffset; + nextOffset += objectToWrite->nRequiredPropertyExtraData * sizeof(QV4::CompiledData::RequiredPropertyExtraData); + quint32_le *functionsTable = reinterpret_cast<quint32_le *>(objectPtr + objectToWrite->offsetToFunctions); for (const Function *f = o->firstFunction(); f; f = f->next) *functionsTable++ = o->runtimeFunctionIndices.at(f->index); @@ -1694,6 +1798,22 @@ void QmlUnitGenerator::generate(Document &output, const QV4::CompiledData::Depen for (int i = 0; i < o->namedObjectsInComponent.size(); ++i) { *namedObjectInComponentPtr++ = o->namedObjectsInComponent.at(i); } + + char *inlineComponentPtr = objectPtr + objectToWrite->offsetToInlineComponents; + for (auto it = o->inlineComponentsBegin(); it != o->inlineComponentsEnd(); ++it) { + const InlineComponent *ic = it.ptr; + QV4::CompiledData::InlineComponent *icToWrite = reinterpret_cast<QV4::CompiledData::InlineComponent*>(inlineComponentPtr); + *icToWrite = *ic; + inlineComponentPtr += sizeof(QV4::CompiledData::InlineComponent); + } + + char *requiredPropertyExtraDataPtr = objectPtr + objectToWrite->offsetToRequiredPropertyExtraData; + for (auto it = o->requiredPropertyExtraDataBegin(); it != o->requiredPropertyExtraDataEnd(); ++it) { + const RequiredPropertyExtraData *extraData = it.ptr; + QV4::CompiledData::RequiredPropertyExtraData *extraDataToWrite = reinterpret_cast<QV4::CompiledData::RequiredPropertyExtraData*>(requiredPropertyExtraDataPtr); + *extraDataToWrite = *extraData; + requiredPropertyExtraDataPtr += sizeof(QV4::CompiledData::RequiredPropertyExtraData); + } } if (!output.javaScriptCompilationUnit.data) { @@ -1841,12 +1961,14 @@ bool JSCodeGen::generateCodeForComponents(const QVector<quint32> &componentRoots bool JSCodeGen::compileComponent(int contextObject) { const QmlIR::Object *obj = document->objects.at(contextObject); - if (obj->flags & QV4::CompiledData::Object::IsComponent) { + if (obj->flags & QV4::CompiledData::Object::IsComponent && !obj->isInlineComponent) { Q_ASSERT(obj->bindingCount() == 1); const QV4::CompiledData::Binding *componentBinding = obj->firstBinding(); Q_ASSERT(componentBinding->type == QV4::CompiledData::Binding::Type_Object); contextObject = componentBinding->value.objectIndex; } + for (auto it = obj->inlineComponentsBegin(); it != obj->inlineComponentsEnd(); ++it) + compileComponent(it->objectIndex); return compileJavaScriptCodeInObjectsRecursively(contextObject, contextObject); } @@ -1854,7 +1976,7 @@ bool JSCodeGen::compileComponent(int contextObject) bool JSCodeGen::compileJavaScriptCodeInObjectsRecursively(int objectIndex, int scopeObjectIndex) { QmlIR::Object *object = document->objects.at(objectIndex); - if (object->flags & QV4::CompiledData::Object::IsComponent) + if (object->flags & QV4::CompiledData::Object::IsComponent && !object->isInlineComponent) return true; if (object->functionsAndExpressions->count > 0) { diff --git a/src/qml/compiler/qqmlirbuilder_p.h b/src/qml/compiler/qqmlirbuilder_p.h index 4279f5b768..9629a73199 100644 --- a/src/qml/compiler/qqmlirbuilder_p.h +++ b/src/qml/compiler/qqmlirbuilder_p.h @@ -158,6 +158,13 @@ struct PoolList } struct Iterator { + // turn Iterator into a proper iterator + using iterator_category = std::forward_iterator_tag; + using value_type = T; + using difference_type = ptrdiff_t; + using pointer = T *; + using reference = T &; + T *ptr; explicit Iterator(T *p) : ptr(p) {} @@ -178,8 +185,15 @@ struct PoolList return *ptr; } - void operator++() { + Iterator& operator++() { + ptr = ptr->next; + return *this; + } + + Iterator operator++(int) { + Iterator that {ptr}; ptr = ptr->next; + return that; } bool operator==(const Iterator &rhs) const { @@ -193,6 +207,8 @@ struct PoolList Iterator begin() { return Iterator(first); } Iterator end() { return Iterator(nullptr); } + + using iterator = Iterator; }; struct Object; @@ -259,11 +275,21 @@ struct Binding : public QV4::CompiledData::Binding Binding *next; }; +struct InlineComponent : public QV4::CompiledData::InlineComponent +{ + InlineComponent *next; +}; + struct Alias : public QV4::CompiledData::Alias { Alias *next; }; +struct RequiredPropertyExtraData : public QV4::CompiledData::RequiredPropertyExtraData +{ + RequiredPropertyExtraData *next; +}; + struct Function { QV4::CompiledData::Location location; @@ -300,6 +326,7 @@ public: int id; int indexOfDefaultPropertyOrAlias; bool defaultPropertyIsAlias; + bool isInlineComponent = false; quint32 flags; QV4::CompiledData::Location location; @@ -317,6 +344,11 @@ public: int bindingCount() const { return bindings->count; } const Function *firstFunction() const { return functions->first; } int functionCount() const { return functions->count; } + const InlineComponent *inlineComponent() const { return inlineComponents->first; } + int inlineComponentCount() const { return inlineComponents->count; } + const RequiredPropertyExtraData *requiredPropertyExtraData() const {return requiredPropertyExtraDatas->first; } + int requiredPropertyExtraDataCount() const { return requiredPropertyExtraDatas->count; } + void simplifyRequiredProperties(); PoolList<Binding>::Iterator bindingsBegin() const { return bindings->begin(); } PoolList<Binding>::Iterator bindingsEnd() const { return bindings->end(); } @@ -330,18 +362,24 @@ public: PoolList<Signal>::Iterator signalsEnd() const { return qmlSignals->end(); } PoolList<Function>::Iterator functionsBegin() const { return functions->begin(); } PoolList<Function>::Iterator functionsEnd() const { return functions->end(); } + PoolList<InlineComponent>::Iterator inlineComponentsBegin() const { return inlineComponents->begin(); } + PoolList<InlineComponent>::Iterator inlineComponentsEnd() const { return inlineComponents->end(); } + PoolList<RequiredPropertyExtraData>::Iterator requiredPropertyExtraDataBegin() const {return requiredPropertyExtraDatas->begin(); } + PoolList<RequiredPropertyExtraData>::Iterator requiredPropertyExtraDataEnd() const {return requiredPropertyExtraDatas->end(); } // If set, then declarations for this object (and init bindings for these) should go into the // specified object. Used for declarations inside group properties. Object *declarationsOverride; - void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::AST::SourceLocation &location = QQmlJS::AST::SourceLocation()); + void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QQmlJS::SourceLocation &location = QQmlJS::SourceLocation()); QString appendEnum(Enum *enumeration); QString appendSignal(Signal *signal); - QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation); - QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::AST::SourceLocation &defaultToken, QQmlJS::AST::SourceLocation *errorLocation); + QString appendProperty(Property *prop, const QString &propertyName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation); + QString appendAlias(Alias *prop, const QString &aliasName, bool isDefaultProperty, const QQmlJS::SourceLocation &defaultToken, QQmlJS::SourceLocation *errorLocation); void appendFunction(QmlIR::Function *f); + void appendInlineComponent(InlineComponent *ic); + void appendRequiredPropertyExtraData(RequiredPropertyExtraData *extraData); QString appendBinding(Binding *b, bool isListBinding); Binding *findBinding(quint32 nameIndex) const; @@ -365,6 +403,8 @@ private: PoolList<Signal> *qmlSignals; PoolList<Binding> *bindings; PoolList<Function> *functions; + PoolList<InlineComponent> *inlineComponents; + PoolList<RequiredPropertyExtraData> *requiredPropertyExtraDatas; }; struct Q_QMLCOMPILER_PRIVATE_EXPORT Pragma @@ -393,6 +433,9 @@ struct Q_QMLCOMPILER_PRIVATE_EXPORT Document int registerString(const QString &str) { return jsGenerator.registerString(str); } QString stringAt(int index) const { return jsGenerator.stringForIndex(index); } + + int objectCount() const {return objects.size();} + Object* objectAt(int i) const {return objects.at(i);} }; class Q_QMLCOMPILER_PRIVATE_EXPORT ScriptDirectivesCollector : public QQmlJS::Directives @@ -433,31 +476,33 @@ public: bool visit(QQmlJS::AST::UiArrayBinding *ast) override; bool visit(QQmlJS::AST::UiObjectBinding *ast) override; bool visit(QQmlJS::AST::UiObjectDefinition *ast) override; + bool visit(QQmlJS::AST::UiInlineComponent *ast) override; bool visit(QQmlJS::AST::UiEnumDeclaration *ast) override; bool visit(QQmlJS::AST::UiPublicMember *ast) override; bool visit(QQmlJS::AST::UiScriptBinding *ast) override; bool visit(QQmlJS::AST::UiSourceElement *ast) override; + bool visit(QQmlJS::AST::UiRequired *ast) override; void throwRecursionDepthError() override { - recordError(QQmlJS::AST::SourceLocation(), + recordError(QQmlJS::SourceLocation(), QStringLiteral("Maximum statement or expression depth exceeded")); } void accept(QQmlJS::AST::Node *node); // returns index in _objects - bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::AST::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr); + bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiQualifiedId *qualifiedTypeNameId, const QQmlJS::SourceLocation &location, QQmlJS::AST::UiObjectInitializer *initializer, Object *declarationsOverride = nullptr); bool defineQMLObject(int *objectIndex, QQmlJS::AST::UiObjectDefinition *node, Object *declarationsOverride = nullptr) { return defineQMLObject(objectIndex, node->qualifiedTypeNameId, node->qualifiedTypeNameId->firstSourceLocation(), node->initializer, declarationsOverride); } static QString asString(QQmlJS::AST::UiQualifiedId *node); QStringRef asStringRef(QQmlJS::AST::Node *node); static void extractVersion(const QStringRef &string, int *maj, int *min); - QStringRef textRefAt(const QQmlJS::AST::SourceLocation &loc) const + QStringRef textRefAt(const QQmlJS::SourceLocation &loc) const { return QStringRef(&sourceCode, loc.offset, loc.length); } - QStringRef textRefAt(const QQmlJS::AST::SourceLocation &first, - const QQmlJS::AST::SourceLocation &last) const; + QStringRef textRefAt(const QQmlJS::SourceLocation &first, + const QQmlJS::SourceLocation &last) const; void setBindingValue(QV4::CompiledData::Binding *binding, QQmlJS::AST::Statement *statement, QQmlJS::AST::Node *parentNode); @@ -466,24 +511,24 @@ public: void appendBinding(QQmlJS::AST::UiQualifiedId *name, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode); void appendBinding(QQmlJS::AST::UiQualifiedId *name, int objectIndex, bool isOnAssignment = false); - void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, - const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, + void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, + const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, QQmlJS::AST::Statement *value, QQmlJS::AST::Node *parentNode); - void appendBinding(const QQmlJS::AST::SourceLocation &qualifiedNameLocation, - const QQmlJS::AST::SourceLocation &nameLocation, quint32 propertyNameIndex, + void appendBinding(const QQmlJS::SourceLocation &qualifiedNameLocation, + const QQmlJS::SourceLocation &nameLocation, quint32 propertyNameIndex, int objectIndex, bool isListItem = false, bool isOnAssignment = false); bool appendAlias(QQmlJS::AST::UiPublicMember *node); Object *bindingsTarget() const; - bool setId(const QQmlJS::AST::SourceLocation &idLocation, QQmlJS::AST::Statement *value); + bool setId(const QQmlJS::SourceLocation &idLocation, QQmlJS::AST::Statement *value); // resolves qualified name (font.pixelSize for example) and returns the last name along // with the object any right-hand-side of a binding should apply to. bool resolveQualifiedId(QQmlJS::AST::UiQualifiedId **nameToResolve, Object **object, bool onAssignment = false); - void recordError(const QQmlJS::AST::SourceLocation &location, const QString &description); + void recordError(const QQmlJS::SourceLocation &location, const QString &description); quint32 registerString(const QString &str) const { return jsGenerator->registerString(str); } template <typename _Tp> _Tp *New() { return pool->New<_Tp>(); } @@ -493,11 +538,12 @@ public: static bool isStatementNodeScript(QQmlJS::AST::Statement *statement); static bool isRedundantNullInitializerForPropertyDeclaration(Property *property, QQmlJS::AST::Statement *statement); - QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::AST::SourceLocation *errorLocation); + QString sanityCheckFunctionNames(Object *obj, const QSet<QString> &illegalNames, QQmlJS::SourceLocation *errorLocation); QList<QQmlJS::DiagnosticMessage> errors; QSet<QString> illegalNames; + QSet<QString> inlineComponentsNames; QList<const QV4::CompiledData::Import *> _imports; QList<Pragma*> _pragmas; @@ -511,6 +557,8 @@ public: QQmlJS::MemoryPool *pool; QString sourceCode; QV4::Compiler::JSUnitGenerator *jsGenerator; + + bool insideInlineComponent = false; }; struct Q_QMLCOMPILER_PRIVATE_EXPORT QmlUnitGenerator diff --git a/src/qml/compiler/qv4bytecodegenerator.cpp b/src/qml/compiler/qv4bytecodegenerator.cpp index 7df1614ffe..f8a41edb6a 100644 --- a/src/qml/compiler/qv4bytecodegenerator.cpp +++ b/src/qml/compiler/qv4bytecodegenerator.cpp @@ -45,7 +45,7 @@ QT_USE_NAMESPACE using namespace QV4; using namespace Moth; -void BytecodeGenerator::setLocation(const QQmlJS::AST::SourceLocation &loc) +void BytecodeGenerator::setLocation(const QQmlJS::SourceLocation &loc) { currentLine = static_cast<int>(loc.startLine); } diff --git a/src/qml/compiler/qv4bytecodegenerator_p.h b/src/qml/compiler/qv4bytecodegenerator_p.h index 8c509dd9f1..1895a34a68 100644 --- a/src/qml/compiler/qv4bytecodegenerator_p.h +++ b/src/qml/compiler/qv4bytecodegenerator_p.h @@ -56,10 +56,8 @@ QT_BEGIN_NAMESPACE namespace QQmlJS { -namespace AST { class SourceLocation; } -} namespace QV4 { @@ -244,7 +242,7 @@ QT_WARNING_POP - void setLocation(const QQmlJS::AST::SourceLocation &loc); + void setLocation(const QQmlJS::SourceLocation &loc); ExceptionHandler *exceptionHandler() const { return currentExceptionHandler; diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index c43ea64e2e..4588690307 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1371,6 +1371,40 @@ bool Codegen::visit(BinaryExpression *ast) setExprResult(Reference::fromAccumulator(this)); } return false; + } else if (ast->op == QSOperator::Coalesce) { + + Reference left = expression(ast->left); + if (hasError()) + return false; + + BytecodeGenerator::Label iftrue = bytecodeGenerator->newLabel(); + BytecodeGenerator::Label iffalse = bytecodeGenerator->newLabel(); + + Instruction::CmpNeNull cmp; + + left = left.storeOnStack(); + left.loadInAccumulator(); + bytecodeGenerator->addInstruction(cmp); + + bytecodeGenerator->jumpTrue().link(iftrue); + bytecodeGenerator->jumpFalse().link(iffalse); + + blockTailCalls.unblock(); + + iftrue.link(); + + left.loadInAccumulator(); + + BytecodeGenerator::Jump jump_endif = bytecodeGenerator->jump(); + + iffalse.link(); + + Reference right = expression(ast->right); + right.loadInAccumulator(); + jump_endif.link(); + setExprResult(Reference::fromAccumulator(this)); + + return false; } else if (ast->op == QSOperator::Assign) { if (AST::Pattern *p = ast->left->patternCast()) { RegisterScope scope(this); @@ -1497,7 +1531,9 @@ bool Codegen::visit(BinaryExpression *ast) break; } - + case QSOperator::As: + setExprResult(left); + break; } // switch return false; @@ -3785,8 +3821,7 @@ void Codegen::throwError(ErrorType errorType, const SourceLocation &loc, const Q _errorType = errorType; _error.message = detail; - _error.line = loc.startLine; - _error.column = loc.startColumn; + _error.loc = loc; } void Codegen::throwSyntaxError(const SourceLocation &loc, const QString &detail) @@ -4069,7 +4104,7 @@ Codegen::Reference Codegen::Reference::asLValue() const case Accumulator: Q_UNREACHABLE(); case Super: - codegen->throwSyntaxError(AST::SourceLocation(), QStringLiteral("Super lvalues not implemented.")); + codegen->throwSyntaxError(SourceLocation(), QStringLiteral("Super lvalues not implemented.")); return *this; case Member: if (!propertyBase.isStackSlot()) { diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index 82a4fc3289..255698d790 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -661,12 +661,12 @@ protected: bool visit(QQmlJS::AST::UiSourceElement *ast) override; bool throwSyntaxErrorOnEvalOrArgumentsInStrictMode(const Reference &r, - const QQmlJS::AST::SourceLocation &loc); - virtual void throwSyntaxError(const QQmlJS::AST::SourceLocation &loc, const QString &detail); - virtual void throwReferenceError(const QQmlJS::AST::SourceLocation &loc, const QString &detail); + const QQmlJS::SourceLocation &loc); + virtual void throwSyntaxError(const QQmlJS::SourceLocation &loc, const QString &detail); + virtual void throwReferenceError(const QQmlJS::SourceLocation &loc, const QString &detail); void throwRecursionDepthError() override { - throwSyntaxError(QQmlJS::AST::SourceLocation(), + throwSyntaxError(QQmlJS::SourceLocation(), QStringLiteral("Maximum statement or expression depth exceeded")); } @@ -700,7 +700,7 @@ public: Reference referenceForName( const QString &name, bool lhs, - const QQmlJS::AST::SourceLocation &accessLocation = QQmlJS::AST::SourceLocation()); + const QQmlJS::SourceLocation &accessLocation = QQmlJS::SourceLocation()); QV4::CompiledData::CompilationUnit generateCompilationUnit(bool generateUnitData = true); static QV4::CompiledData::CompilationUnit compileModule( @@ -810,7 +810,7 @@ protected: private: VolatileMemoryLocations scanVolatileMemoryLocations(QQmlJS::AST::Node *ast); void handleConstruct(const Reference &base, QQmlJS::AST::ArgumentList *args); - void throwError(ErrorType errorType, const QQmlJS::AST::SourceLocation &loc, + void throwError(ErrorType errorType, const QQmlJS::SourceLocation &loc, const QString &detail); }; diff --git a/src/qml/compiler/qv4compilercontext.cpp b/src/qml/compiler/qv4compilercontext.cpp index 88837b0feb..872fc94dc9 100644 --- a/src/qml/compiler/qv4compilercontext.cpp +++ b/src/qml/compiler/qv4compilercontext.cpp @@ -45,6 +45,7 @@ QT_USE_NAMESPACE using namespace QV4; using namespace QV4::Compiler; using namespace QQmlJS::AST; +using namespace QQmlJS; QT_BEGIN_NAMESPACE @@ -86,7 +87,7 @@ bool Context::Member::requiresTDZCheck(const SourceLocation &accessLocation, boo } bool Context::addLocalVar(const QString &name, Context::MemberType type, VariableScope scope, FunctionExpression *function, - const QQmlJS::AST::SourceLocation &endOfInitializer) + const QQmlJS::SourceLocation &endOfInitializer) { // ### can this happen? if (name.isEmpty()) @@ -122,7 +123,7 @@ bool Context::addLocalVar(const QString &name, Context::MemberType type, Variabl return true; } -Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::AST::SourceLocation &accessLocation) +Context::ResolvedName Context::resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation) { int scope = 0; Context *c = this; diff --git a/src/qml/compiler/qv4compilercontext_p.h b/src/qml/compiler/qv4compilercontext_p.h index 8c124ac409..4a14009c35 100644 --- a/src/qml/compiler/qv4compilercontext_p.h +++ b/src/qml/compiler/qv4compilercontext_p.h @@ -183,10 +183,10 @@ struct Context { QQmlJS::AST::VariableScope scope = QQmlJS::AST::VariableScope::Var; mutable bool canEscape = false; QQmlJS::AST::FunctionExpression *function = nullptr; - QQmlJS::AST::SourceLocation endOfInitializerLocation; + QQmlJS::SourceLocation endOfInitializerLocation; bool isLexicallyScoped() const { return this->scope != QQmlJS::AST::VariableScope::Var; } - bool requiresTDZCheck(const QQmlJS::AST::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const; + bool requiresTDZCheck(const QQmlJS::SourceLocation &accessLocation, bool accessAcrossContextBoundaries) const; }; typedef QMap<QString, Member> MemberMap; @@ -227,7 +227,7 @@ struct Context { bool isWithBlock = false; bool isCatchBlock = false; QString caughtVariable; - QQmlJS::AST::SourceLocation lastBlockInitializerLocation; + QQmlJS::SourceLocation lastBlockInitializerLocation; enum UsesArgumentsObject { ArgumentsObjectUnknown, @@ -331,7 +331,7 @@ struct Context { } bool addLocalVar(const QString &name, MemberType contextType, QQmlJS::AST::VariableScope scope, QQmlJS::AST::FunctionExpression *function = nullptr, - const QQmlJS::AST::SourceLocation &endOfInitializer = QQmlJS::AST::SourceLocation()); + const QQmlJS::SourceLocation &endOfInitializer = QQmlJS::SourceLocation()); struct ResolvedName { enum Type { @@ -348,10 +348,10 @@ struct Context { bool requiresTDZCheck = false; int scope = -1; int index = -1; - QQmlJS::AST::SourceLocation endOfDeclarationLocation; + QQmlJS::SourceLocation endOfDeclarationLocation; bool isValid() const { return type != Unresolved; } }; - ResolvedName resolveName(const QString &name, const QQmlJS::AST::SourceLocation &accessLocation); + ResolvedName resolveName(const QString &name, const QQmlJS::SourceLocation &accessLocation); void emitBlockHeader(Compiler::Codegen *codegen); void emitBlockFooter(Compiler::Codegen *codegen); diff --git a/src/qml/compiler/qv4compilerscanfunctions.cpp b/src/qml/compiler/qv4compilerscanfunctions.cpp index ab0ebf3d4b..a1ddee8234 100644 --- a/src/qml/compiler/qv4compilerscanfunctions.cpp +++ b/src/qml/compiler/qv4compilerscanfunctions.cpp @@ -55,7 +55,7 @@ using namespace QV4::Compiler; using namespace QQmlJS; using namespace QQmlJS::AST; -static CompiledData::Location location(const QQmlJS::AST::SourceLocation &astLocation) +static CompiledData::Location location(const QQmlJS::SourceLocation &astLocation) { CompiledData::Location target; target.line = astLocation.startLine; @@ -129,7 +129,7 @@ void ScanFunctions::checkDirectivePrologue(StatementList *ast) } } -void ScanFunctions::checkName(const QStringRef &name, const SourceLocation &loc) +void ScanFunctions::checkName(const QStringRef &name, const QQmlJS::SourceLocation &loc) { if (_context->isStrict) { if (name == QLatin1String("implements") @@ -330,7 +330,7 @@ bool ScanFunctions::visit(PatternElement *ast) BoundNames names; ast->boundNames(&names); - QQmlJS::AST::SourceLocation lastInitializerLocation = ast->lastSourceLocation(); + QQmlJS::SourceLocation lastInitializerLocation = ast->lastSourceLocation(); if (_context->lastBlockInitializerLocation.isValid()) lastInitializerLocation = _context->lastBlockInitializerLocation; diff --git a/src/qml/compiler/qv4compilerscanfunctions_p.h b/src/qml/compiler/qv4compilerscanfunctions_p.h index 2de80eac44..e39aa2454e 100644 --- a/src/qml/compiler/qv4compilerscanfunctions_p.h +++ b/src/qml/compiler/qv4compilerscanfunctions_p.h @@ -97,7 +97,7 @@ protected: void checkDirectivePrologue(QQmlJS::AST::StatementList *ast); - void checkName(const QStringRef &name, const QQmlJS::AST::SourceLocation &loc); + void checkName(const QStringRef &name, const QQmlJS::SourceLocation &loc); bool visit(QQmlJS::AST::Program *ast) override; void endVisit(QQmlJS::AST::Program *) override; |