Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qqmltypecompiler.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
5
6#include <private/qqmlobjectcreator_p.h>
7#include <private/qqmlcustomparser_p.h>
8#include <private/qqmlvmemetaobject_p.h>
9#include <private/qqmlcomponent_p.h>
10#include <private/qqmlpropertyresolver_p.h>
11#include <private/qqmlcomponentandaliasresolver_p.h>
12#include <private/qqmlsignalnames_p.h>
13
14#define COMPILE_EXCEPTION(token, desc) \
15 { \
16 recordError((token)->location, desc); \
17 return false; \
18 }
19
21
23 disableInternalDeferredProperties, QML_DISABLE_INTERNAL_DEFERRED_PROPERTIES);
24
25Q_LOGGING_CATEGORY(lcQmlTypeCompiler, "qt.qml.typecompiler");
26
30 const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
31 : resolvedTypes(resolvedTypeCache)
32 , engine(engine)
33 , dependencyHasher(dependencyHasher)
34 , document(parsedQML)
35 , typeData(typeData)
36{
37}
38
39QQmlRefPointer<QV4::CompiledData::CompilationUnit> QQmlTypeCompiler::compile()
40{
41 // Build property caches and VME meta object data
42
44 it != end; ++it) {
45 QQmlCustomParser *customParser = (*it)->type().customParser();
46 if (customParser)
47 customParsers.insert(it.key(), customParser);
48 }
49
50 QQmlPendingGroupPropertyBindings pendingGroupPropertyBindings;
51
52
53 {
54 QQmlPropertyCacheCreator<QQmlTypeCompiler> propertyCacheBuilder(&m_propertyCaches, &pendingGroupPropertyBindings,
55 engine, this, imports(), typeData->typeClassName());
56 QQmlError cycleError = propertyCacheBuilder.verifyNoICCycle();
57 if (cycleError.isValid()) {
58 recordError(cycleError);
59 return nullptr;
60 }
62 do {
63 result = propertyCacheBuilder.buildMetaObjectsIncrementally();
64 const QQmlError &error = result.error;
65 if (error.isValid()) {
67 return nullptr;
68 } else {
69 // Resolve component boundaries and aliases
70
71 QQmlComponentAndAliasResolver resolver(this, enginePrivate(), &m_propertyCaches);
72 if (QQmlError error = resolver.resolve(result.processedRoot); error.isValid()) {
74 return nullptr;
75 }
76 pendingGroupPropertyBindings.resolveMissingPropertyCaches(&m_propertyCaches);
77 pendingGroupPropertyBindings.clear(); // anything that can be processed is now processed
78 }
79 } while (result.canResume);
80 }
81
82 {
83 QQmlDefaultPropertyMerger merger(this);
84 merger.mergeDefaultProperties();
85 }
86
87 {
88 SignalHandlerResolver converter(this);
89 if (!converter.resolveSignalHandlerExpressions())
90 return nullptr;
91 }
92
93 {
94 QQmlEnumTypeResolver enumResolver(this);
95 if (!enumResolver.resolveEnumBindings())
96 return nullptr;
97 }
98
99 {
101 cpi.annotateBindingsWithScriptStrings();
102 }
103
104 {
105 QQmlAliasAnnotator annotator(this);
106 annotator.annotateBindingsToAliases();
107 }
108
109 {
110 QQmlDeferredAndCustomParserBindingScanner deferredAndCustomParserBindingScanner(this);
111 if (!deferredAndCustomParserBindingScanner.scanObject())
112 return nullptr;
113 }
114
115 if (!document->javaScriptCompilationUnit || !document->javaScriptCompilationUnit->unitData()) {
116 // Compile JS binding expressions and signal handlers if necessary
117 {
118 // We can compile script strings ahead of time, but they must be compiled
119 // without type optimizations as their scope is always entirely dynamic.
120 QQmlScriptStringScanner sss(this);
121 sss.scan();
122 }
123
124 document->jsModule.fileName = typeData->urlString();
125 document->jsModule.finalUrl = typeData->finalUrlString();
126 QmlIR::JSCodeGen v4CodeGenerator(document, engine->v4engine()->illegalNames());
127 for (QmlIR::Object *object : std::as_const(document->objects)) {
128 if (!v4CodeGenerator.generateRuntimeFunctions(object)) {
129 Q_ASSERT(v4CodeGenerator.hasError());
130 recordError(v4CodeGenerator.error());
131 return nullptr;
132 }
133 }
134 document->javaScriptCompilationUnit = v4CodeGenerator.generateCompilationUnit(/*generated unit data*/false);
135 }
136
137 // Generate QML compiled type data structures
138
139 QmlIR::QmlUnitGenerator qmlGenerator;
140 qmlGenerator.generate(*document, dependencyHasher);
141
142 if (!errors.isEmpty())
143 return nullptr;
144
145 return std::move(document->javaScriptCompilationUnit);
146}
147
149{
151 error.setLine(qmlConvertSourceCoordinate<quint32, int>(location.line()));
152 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(location.column()));
153 error.setDescription(description);
154 error.setUrl(url());
155 errors << error;
156}
157
159{
161 error.setDescription(message.message);
162 error.setLine(qmlConvertSourceCoordinate<quint32, int>(message.loc.startLine));
163 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(message.loc.startColumn));
164 error.setUrl(url());
165 errors << error;
166}
167
169{
170 QQmlError error = e;
171 error.setUrl(url());
172 errors << error;
173}
174
176{
177 return document->stringAt(idx);
178}
179
181{
182 return document->jsGenerator.registerString(str);
183}
184
189
194
196{
197 return typeData->imports();
198}
199
200QVector<QmlIR::Object *> *QQmlTypeCompiler::qmlObjects() const
201{
202 return &document->objects;
203}
204
206{
207 return &m_propertyCaches;
208}
209
211{
212 return &m_propertyCaches;
213}
214
219
221{
222 return document->jsParserEngine.newStringRef(string);
223}
224
229
230QString QQmlTypeCompiler::bindingAsString(const QmlIR::Object *object, int scriptIndex) const
231{
232 return object->bindingAsString(document, scriptIndex);
233}
234
235void QQmlTypeCompiler::addImport(const QString &module, const QString &qualifier, QTypeRevision version)
236{
237 const quint32 moduleIdx = registerString(module);
238 const quint32 qualifierIdx = registerString(qualifier);
239
240 for (int i = 0, count = document->imports.size(); i < count; ++i) {
241 const QV4::CompiledData::Import *existingImport = document->imports.at(i);
242 if (existingImport->type == QV4::CompiledData::Import::ImportLibrary
243 && existingImport->uriIndex == moduleIdx
244 && existingImport->qualifierIndex == qualifierIdx)
245 return;
246 }
247 auto pool = memoryPool();
248 QV4::CompiledData::Import *import = pool->New<QV4::CompiledData::Import>();
250 import->version = version;
251 import->uriIndex = moduleIdx;
252 import->qualifierIndex = qualifierIdx;
253 document->imports.append(import);
254}
255
257{
258 return typeData->qmlType(inlineComponentName);
259}
260
262 : compiler(typeCompiler)
263{
264}
265
267 : QQmlCompilePass(typeCompiler)
268 , enginePrivate(typeCompiler->enginePrivate())
269 , qmlObjects(*typeCompiler->qmlObjects())
270 , imports(typeCompiler->imports())
271 , customParsers(typeCompiler->customParserCache())
272 , illegalNames(typeCompiler->enginePrivate()->v4engine()->illegalNames())
273 , propertyCaches(typeCompiler->propertyCaches())
274{
275}
276
278{
279 for (int objectIndex = 0; objectIndex < qmlObjects.size(); ++objectIndex) {
280 const QmlIR::Object * const obj = qmlObjects.at(objectIndex);
281 QQmlPropertyCache::ConstPtr cache = propertyCaches->at(objectIndex);
282 if (!cache)
283 continue;
284 if (QQmlCustomParser *customParser = customParsers.value(obj->inheritedTypeNameIndex)) {
285 if (!(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers))
286 continue;
287 }
288 const QString elementName = stringAt(obj->inheritedTypeNameIndex);
289 if (!resolveSignalHandlerExpressions(obj, elementName, cache))
290 return false;
291 }
292 return true;
293}
294
296 const QmlIR::Object *obj, const QString &typeName,
297 const QQmlPropertyCache::ConstPtr &propertyCache)
298{
299 // map from signal name defined in qml itself to list of parameters
300 QHash<QString, QStringList> customSignals;
301
302 for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
303 const QString bindingPropertyName = stringAt(binding->propertyNameIndex);
304 // Attached property?
305 const QV4::CompiledData::Binding::Type bindingType = binding->type();
307 const QmlIR::Object *attachedObj = qmlObjects.at(binding->value.objectIndex);
308 auto *typeRef = resolvedType(binding->propertyNameIndex);
309 QQmlType type = typeRef ? typeRef->type() : QQmlType();
310 if (!type.isValid()) {
311 imports->resolveType(
312 QQmlTypeLoader::get(enginePrivate), bindingPropertyName, &type, nullptr,
313 nullptr);
314 }
315
316 const QMetaObject *attachedType = type.attachedPropertiesType(enginePrivate);
317 if (!attachedType)
318 COMPILE_EXCEPTION(binding, tr("Non-existent attached object"));
320 if (!resolveSignalHandlerExpressions(attachedObj, bindingPropertyName, cache))
321 return false;
322 continue;
323 }
324
325 QString qPropertyName;
326 QString signalName;
327 if (auto propertyName =
329 qPropertyName = *propertyName;
330 signalName = *QQmlSignalNames::changedHandlerNameToSignalName(bindingPropertyName);
331 } else {
332 signalName = QQmlSignalNames::handlerNameToSignalName(bindingPropertyName)
333 .value_or(QString());
334 }
335 if (signalName.isEmpty())
336 continue;
337
338 QQmlPropertyResolver resolver(propertyCache);
339
340 bool notInRevision = false;
341 const QQmlPropertyData * const signal = resolver.signal(signalName, &notInRevision);
342 const QQmlPropertyData * const signalPropertyData = resolver.property(signalName, /*notInRevision ptr*/nullptr);
343 const QQmlPropertyData * const qPropertyData = !qPropertyName.isEmpty() ? resolver.property(qPropertyName) : nullptr;
344 QString finalSignalHandlerPropertyName = signalName;
347
348 const bool isPropertyObserver = !signalPropertyData && qPropertyData && qPropertyData->isBindable();
349 if (signal && !(qPropertyData && qPropertyData->isAlias() && isPropertyObserver)) {
350 int sigIndex = propertyCache->methodIndexToSignalIndex(signal->coreIndex());
351 sigIndex = propertyCache->originalClone(sigIndex);
352
353 bool unnamedParameter = false;
354
355 QList<QByteArray> parameterNames = propertyCache->signalParameterNames(sigIndex);
356 for (int i = 0; i < parameterNames.size(); ++i) {
357 const QString param = QString::fromUtf8(parameterNames.at(i));
358 if (param.isEmpty())
359 unnamedParameter = true;
360 else if (unnamedParameter) {
361 COMPILE_EXCEPTION(binding, tr("Signal uses unnamed parameter followed by named parameter."));
362 } else if (illegalNames.contains(param)) {
363 COMPILE_EXCEPTION(binding, tr("Signal parameter \"%1\" hides global variable.").arg(param));
364 }
365 }
366 } else if (isPropertyObserver) {
367 finalSignalHandlerPropertyName = qPropertyName;
369 } else {
370 if (notInRevision) {
371 // Try assinging it as a property later
372 if (signalPropertyData)
373 continue;
374
375 const QString &originalPropertyName = stringAt(binding->propertyNameIndex);
376
377 auto *typeRef = resolvedType(obj->inheritedTypeNameIndex);
378 const QQmlType type = typeRef ? typeRef->type() : QQmlType();
379 if (type.isValid()) {
380 COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available in %3 %4.%5.")
381 .arg(typeName).arg(originalPropertyName).arg(type.module())
382 .arg(type.version().majorVersion())
383 .arg(type.version().minorVersion()));
384 } else {
385 COMPILE_EXCEPTION(binding, tr("\"%1.%2\" is not available due to component versioning.").arg(typeName).arg(originalPropertyName));
386 }
387 }
388
389 // Try to look up the signal parameter names in the object itself
390
391 // build cache if necessary
392 if (customSignals.isEmpty()) {
393 for (const QmlIR::Signal *signal = obj->firstSignal(); signal; signal = signal->next) {
394 const QString &signalName = stringAt(signal->nameIndex);
395 customSignals.insert(signalName, signal->parameterStringList(compiler->stringPool()));
396 }
397
398 for (const QmlIR::Property *property = obj->firstProperty(); property; property = property->next) {
399 const QString propName = stringAt(property->nameIndex);
400 customSignals.insert(propName, QStringList());
401 }
402 }
403
404 QHash<QString, QStringList>::ConstIterator entry = customSignals.constFind(signalName);
405 if (entry == customSignals.constEnd() && !qPropertyName.isEmpty())
406 entry = customSignals.constFind(qPropertyName);
407
408 if (entry == customSignals.constEnd()) {
409 // Can't find even a custom signal, then just don't do anything and try
410 // keeping the binding as a regular property assignment.
411 continue;
412 }
413 }
414
415 // Binding object to signal means connect the signal to the object's default method.
416 if (bindingType == QV4::CompiledData::Binding::Type_Object) {
418 continue;
419 }
420
421 if (bindingType != QV4::CompiledData::Binding::Type_Script) {
422 if (bindingType < QV4::CompiledData::Binding::Type_Script) {
423 COMPILE_EXCEPTION(binding, tr("Cannot assign a value to a signal (expecting a script to be run)"));
424 } else {
425 COMPILE_EXCEPTION(binding, tr("Incorrectly specified signal assignment"));
426 }
427 }
428
429 binding->propertyNameIndex = compiler->registerString(finalSignalHandlerPropertyName);
430 binding->setFlag(flag);
431 }
432 return true;
433}
434
436 : QQmlCompilePass(typeCompiler)
437 , qmlObjects(*typeCompiler->qmlObjects())
438 , propertyCaches(typeCompiler->propertyCaches())
439 , imports(typeCompiler->imports())
440{
441}
442
444{
445 for (int i = 0; i < qmlObjects.size(); ++i) {
446 QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
447 if (!propertyCache)
448 continue;
449 const QmlIR::Object *obj = qmlObjects.at(i);
450
451 QQmlPropertyResolver resolver(propertyCache);
452
453 for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
454 const QV4::CompiledData::Binding::Flags bindingFlags = binding->flags();
458 continue;
459
460 if (binding->type() != QV4::CompiledData::Binding::Type_Script)
461 continue;
462
463 const QString propertyName = stringAt(binding->propertyNameIndex);
464 bool notInRevision = false;
465 const QQmlPropertyData *pd = resolver.property(propertyName, &notInRevision);
466 if (!pd || pd->isQList())
467 continue;
468
469 if (!pd->isEnum() && pd->propType().id() != QMetaType::Int)
470 continue;
471
472 if (!tryQualifiedEnumAssignment(obj, propertyCache, pd, binding))
473 return false;
474 }
475 }
476
477 return true;
478}
479
480bool QQmlEnumTypeResolver::assignEnumToBinding(QmlIR::Binding *binding, QStringView, int enumValue, bool)
481{
483 binding->value.constantValueIndex = compiler->registerConstant(QV4::Encode((double)enumValue));
484// binding->setNumberValueInternal((double)enumValue);
486 return true;
487}
488
489bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(
490 const QmlIR::Object *obj, const QQmlPropertyCache::ConstPtr &propertyCache,
491 const QQmlPropertyData *prop, QmlIR::Binding *binding)
492{
493 bool isIntProp = (prop->propType().id() == QMetaType::Int) && !prop->isEnum();
494 if (!prop->isEnum() && !isIntProp)
495 return true;
496
497 if (!prop->isWritable()
499 COMPILE_EXCEPTION(binding, tr("Invalid property assignment: \"%1\" is a read-only property")
500 .arg(stringAt(binding->propertyNameIndex)));
501 }
502
504 const QString string = compiler->bindingAsString(obj, binding->value.compiledScriptIndex);
505 if (!string.constData()->isUpper())
506 return true;
507
508 // reject any "complex" expression (even simple arithmetic)
509 // we do this by excluding everything that is not part of a
510 // valid identifier or a dot
511 for (const QChar &c : string)
512 if (!(c.isLetterOrNumber() || c == u'.' || c == u'_' || c.isSpace()))
513 return true;
514
515 // we support one or two '.' in the enum phrase:
516 // * <TypeName>.<EnumValue>
517 // * <TypeName>.<ScopedEnumName>.<EnumValue>
518
519 int dot = string.indexOf(QLatin1Char('.'));
520 if (dot == -1 || dot == string.size()-1)
521 return true;
522
523 int dot2 = string.indexOf(QLatin1Char('.'), dot+1);
524 if (dot2 != -1 && dot2 != string.size()-1) {
525 if (!string.at(dot+1).isUpper())
526 return true;
527 if (string.indexOf(QLatin1Char('.'), dot2+1) != -1)
528 return true;
529 }
530
531 QHashedStringRef typeName(string.constData(), dot);
532 const bool isQtObject = (typeName == QLatin1String("Qt"));
533 const QStringView scopedEnumName = (dot2 != -1 ? QStringView{string}.mid(dot + 1, dot2 - dot - 1) : QStringView());
534 // ### consider supporting scoped enums in Qt namespace
535 const QStringView enumValue = QStringView{string}.mid(!isQtObject && dot2 != -1 ? dot2 + 1 : dot + 1);
536
537 if (isIntProp) { // ### C++11 allows enums to be other integral types. Should we support other integral types here?
538 // Allow enum assignment to ints.
539 bool ok;
540 int enumval = evaluateEnum(typeName.toString(), scopedEnumName, enumValue, &ok);
541 if (ok) {
542 if (!assignEnumToBinding(binding, enumValue, enumval, isQtObject))
543 return false;
544 }
545 return true;
546 }
548 imports->resolveType(
549 QQmlTypeLoader::get(compiler->enginePrivate()), typeName, &type, nullptr, nullptr);
550
551 if (!type.isValid() && !isQtObject)
552 return true;
553
554 int value = 0;
555 bool ok = false;
556
557 auto *tr = resolvedType(obj->inheritedTypeNameIndex);
558
559 // When these two match, we can short cut the search, unless...
560 bool useFastPath = type.isValid() && tr && tr->type() == type;
561 QMetaProperty mprop;
562 QMetaEnum menum;
563 if (useFastPath) {
564 mprop = propertyCache->firstCppMetaObject()->property(prop->coreIndex());
565 menum = mprop.enumerator();
566 // ...the enumerator merely comes from a related metaobject, but the enum scope does not match
567 // the typename we resolved
568 if (!menum.isScoped() && scopedEnumName.isEmpty() && typeName != QString::fromUtf8(menum.scope()))
569 useFastPath = false;;
570 }
571 if (useFastPath) {
572 QByteArray enumName = enumValue.toUtf8();
573 if (menum.isScoped() && !scopedEnumName.isEmpty() && enumName != scopedEnumName.toUtf8())
574 return true;
575
576 if (mprop.isFlagType()) {
577 value = menum.keysToValue(enumName.constData(), &ok);
578 } else {
579 value = menum.keyToValue(enumName.constData(), &ok);
580 }
581 } else {
582 // Otherwise we have to search the whole type
583 if (type.isValid()) {
584 if (!scopedEnumName.isEmpty())
585 value = type.scopedEnumValue(compiler->enginePrivate(), scopedEnumName, enumValue, &ok);
586 else
587 value = type.enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok);
588 } else {
589 QByteArray enumName = enumValue.toUtf8();
590 const QMetaObject *metaObject = &Qt::staticMetaObject;
591 for (int ii = metaObject->enumeratorCount() - 1; !ok && ii >= 0; --ii) {
592 QMetaEnum e = metaObject->enumerator(ii);
593 value = e.keyToValue(enumName.constData(), &ok);
594 }
595 }
596 }
597
598 if (!ok)
599 return true;
600
601 return assignEnumToBinding(binding, enumValue, value, isQtObject);
602}
603
604int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, QStringView enumName, QStringView enumValue, bool *ok) const
605{
606 Q_ASSERT_X(ok, "QQmlEnumTypeResolver::evaluateEnum", "ok must not be a null pointer");
607 *ok = false;
608
609 if (scope != QLatin1String("Qt")) {
611 imports->resolveType(
612 QQmlTypeLoader::get(compiler->enginePrivate()), scope, &type, nullptr, nullptr);
613 if (!type.isValid())
614 return -1;
615 if (!enumName.isEmpty())
616 return type.scopedEnumValue(compiler->enginePrivate(), enumName, enumValue, ok);
618 }
619
620 const QMetaObject *mo = &Qt::staticMetaObject;
621 int i = mo->enumeratorCount();
622 const QByteArray ba = enumValue.toUtf8();
623 while (i--) {
624 int v = mo->enumerator(i).keyToValue(ba.constData(), ok);
625 if (*ok)
626 return v;
627 }
628 return -1;
629}
630
632 : QQmlCompilePass(typeCompiler)
633 , qmlObjects(*typeCompiler->qmlObjects())
634 , customParsers(typeCompiler->customParserCache())
635{
636}
637
639{
640 scanObjectRecursively(/*root object*/0);
641 for (int i = 0; i < qmlObjects.size(); ++i)
642 if (qmlObjects.at(i)->flags & QV4::CompiledData::Object::IsInlineComponentRoot)
643 scanObjectRecursively(i);
644}
645
646void QQmlCustomParserScriptIndexer::scanObjectRecursively(int objectIndex, bool annotateScriptBindings)
647{
648 const QmlIR::Object * const obj = qmlObjects.at(objectIndex);
649 if (!annotateScriptBindings)
650 annotateScriptBindings = customParsers.contains(obj->inheritedTypeNameIndex);
651 for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
652 switch (binding->type()) {
654 if (annotateScriptBindings) {
656 compiler->bindingAsString(obj, binding->value.compiledScriptIndex));
657 }
658 break;
662 scanObjectRecursively(binding->value.objectIndex, annotateScriptBindings);
663 break;
664 default:
665 break;
666 }
667 }
668}
669
671 : QQmlCompilePass(typeCompiler)
672 , qmlObjects(*typeCompiler->qmlObjects())
673 , propertyCaches(typeCompiler->propertyCaches())
674{
675}
676
678{
679 for (int i = 0; i < qmlObjects.size(); ++i) {
680 QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
681 if (!propertyCache)
682 continue;
683
684 const QmlIR::Object *obj = qmlObjects.at(i);
685
686 QQmlPropertyResolver resolver(propertyCache);
687 const QQmlPropertyData *defaultProperty = obj->indexOfDefaultPropertyOrAlias != -1 ? propertyCache->parent()->defaultProperty() : propertyCache->defaultProperty();
688
689 for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
690 if (!binding->isValueBinding())
691 continue;
692 bool notInRevision = false;
693 const QQmlPropertyData *pd = binding->propertyNameIndex != quint32(0) ? resolver.property(stringAt(binding->propertyNameIndex), &notInRevision) : defaultProperty;
694 if (pd && pd->isAlias())
696 }
697 }
698}
699
701 : QQmlCompilePass(typeCompiler)
702 , qmlObjects(*typeCompiler->qmlObjects())
703 , propertyCaches(typeCompiler->propertyCaches())
704{
705
706}
707
709{
710 const QMetaType scriptStringMetaType = QMetaType::fromType<QQmlScriptString>();
711 for (int i = 0; i < qmlObjects.size(); ++i) {
712 QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(i);
713 if (!propertyCache)
714 continue;
715
716 const QmlIR::Object *obj = qmlObjects.at(i);
717
718 QQmlPropertyResolver resolver(propertyCache);
719 const QQmlPropertyData *defaultProperty = obj->indexOfDefaultPropertyOrAlias != -1 ? propertyCache->parent()->defaultProperty() : propertyCache->defaultProperty();
720
721 for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
723 continue;
724 bool notInRevision = false;
725 const QQmlPropertyData *pd = binding->propertyNameIndex != quint32(0) ? resolver.property(stringAt(binding->propertyNameIndex), &notInRevision) : defaultProperty;
726 if (!pd || pd->propType() != scriptStringMetaType)
727 continue;
728
729 QString script = compiler->bindingAsString(obj, binding->value.compiledScriptIndex);
730 binding->stringIndex = compiler->registerString(script);
731 }
732 }
733}
734
735template<>
737 QmlIR::Object *object) const
738{
739 object->namedObjectsInComponent.allocate(m_compiler->memoryPool(), m_idToObjectIndex);
740}
741
742template<>
744{
745 m_compiler->qmlObjects()->at(index)->flags |= QV4::CompiledData::Object::IsComponent;
746 return true;
747}
748
749template<>
751{
752 m_compiler->qmlObjects()->at(index)->id = m_idToObjectIndex.size();
753}
754
755template<>
757{
758 QQmlJS::MemoryPool *pool = m_compiler->memoryPool();
759 QVector<QmlIR::Object *> *qmlObjects = m_compiler->qmlObjects();
760
761 // emulate "import QML 1.0" and then wrap the component in "QML.Component {}"
762 QQmlType componentType = QQmlMetaType::qmlType(
763 &QQmlComponent::staticMetaObject, QStringLiteral("QML"),
765 Q_ASSERT(componentType.isValid());
766 const QString qualifier = QStringLiteral("QML");
767
768 m_compiler->addImport(componentType.module(), qualifier, componentType.version());
769
770 QmlIR::Object *syntheticComponent = pool->New<QmlIR::Object>();
771 syntheticComponent->init(
772 pool,
773 m_compiler->registerString(
774 qualifier + QLatin1Char('.') + componentType.elementName()),
775 m_compiler->registerString(QString()), binding->valueLocation);
776 syntheticComponent->flags |= QV4::CompiledData::Object::IsComponent;
777
778 if (!m_compiler->resolvedTypes->contains(syntheticComponent->inheritedTypeNameIndex)) {
779 auto typeRef = new QV4::ResolvedTypeReference;
780 typeRef->setType(componentType);
781 typeRef->setVersion(componentType.version());
782 m_compiler->resolvedTypes->insert(syntheticComponent->inheritedTypeNameIndex, typeRef);
783 }
784
785 qmlObjects->append(syntheticComponent);
786 const int componentIndex = qmlObjects->size() - 1;
787 // Keep property caches symmetric
788 QQmlPropertyCache::ConstPtr componentCache
789 = QQmlMetaType::propertyCache(&QQmlComponent::staticMetaObject);
790 m_propertyCaches->append(componentCache);
791
792 QmlIR::Binding *syntheticBinding = pool->New<QmlIR::Binding>();
793 *syntheticBinding = *binding;
794
795 // The synthetic binding inside Component has no name. It's just "Component { Foo {} }".
796 syntheticBinding->propertyNameIndex = 0;
797
798 syntheticBinding->setType(QV4::CompiledData::Binding::Type_Object);
799 QString error = syntheticComponent->appendBinding(syntheticBinding, /*isListBinding*/false);
800 Q_ASSERT(error.isEmpty());
802
803 binding->value.objectIndex = componentIndex;
804
805 m_componentRoots.append(componentIndex);
806 return true;
807}
808
809template<>
811 const CompiledObject &component, CompiledBinding *binding)
812{
814 // We cannot make it fail here. It might be a custom-parsed property
815 const int targetObjectIndex = m_idToObjectIndex.value(binding->propertyNameIndex, -1);
816 if (targetObjectIndex != -1)
817 m_propertyCaches->set(binding->value.objectIndex, m_propertyCaches->at(targetObjectIndex));
818}
819
820template<>
821typename QQmlComponentAndAliasResolver<QQmlTypeCompiler>::AliasResolutionResult
823 const CompiledObject &component, int objectIndex, QQmlError *error)
824{
826
827 const QmlIR::Object * const obj = m_compiler->objectAt(objectIndex);
828 if (!obj->aliasCount())
829 return AllAliasesResolved;
830
831 int numResolvedAliases = 0;
832 bool seenUnresolvedAlias = false;
833
834 for (QmlIR::Alias *alias = obj->firstAlias(); alias; alias = alias->next) {
835 if (alias->hasFlag(QV4::CompiledData::Alias::Resolved))
836 continue;
837
838 seenUnresolvedAlias = true;
839
840 const int idIndex = alias->idIndex();
841 const int targetObjectIndex = m_idToObjectIndex.value(idIndex, -1);
842 if (targetObjectIndex == -1) {
844 alias->referenceLocation,
845 tr("Invalid alias reference. Unable to find id \"%1\"").arg(stringAt(idIndex)));
846 break;
847 }
848
849 const QmlIR::Object *targetObject = m_compiler->objectAt(targetObjectIndex);
850 Q_ASSERT(targetObject->id >= 0);
851 alias->setTargetObjectId(targetObject->id);
852 alias->setIsAliasToLocalAlias(false);
853
854 const QString aliasPropertyValue = stringAt(alias->propertyNameIndex);
855
857 QStringView subProperty;
858
859 const int propertySeparator = aliasPropertyValue.indexOf(QLatin1Char('.'));
860 if (propertySeparator != -1) {
861 property = QStringView{aliasPropertyValue}.left(propertySeparator);
862 subProperty = QStringView{aliasPropertyValue}.mid(propertySeparator + 1);
863 } else
864 property = QStringView(aliasPropertyValue);
865
866 QQmlPropertyIndex propIdx;
867
868 if (property.isEmpty()) {
870 } else {
871 QQmlPropertyCache::ConstPtr targetCache = m_propertyCaches->at(targetObjectIndex);
872 if (!targetCache) {
874 alias->referenceLocation,
875 tr("Invalid alias target location: %1").arg(property.toString()));
876 break;
877 }
878
879 QQmlPropertyResolver resolver(targetCache);
880
881 const QQmlPropertyData *targetProperty = resolver.property(property.toString());
882
883 // If it's an alias that we haven't resolved yet, try again later.
884 if (!targetProperty) {
885 bool aliasPointsToOtherAlias = false;
886 int localAliasIndex = 0;
887 for (auto targetAlias = targetObject->aliasesBegin(), end = targetObject->aliasesEnd(); targetAlias != end; ++targetAlias, ++localAliasIndex) {
888 if (stringAt(targetAlias->nameIndex()) == property) {
889 aliasPointsToOtherAlias = true;
890 break;
891 }
892 }
893 if (aliasPointsToOtherAlias) {
894 if (targetObjectIndex == objectIndex) {
895 alias->localAliasIndex = localAliasIndex;
896 alias->setIsAliasToLocalAlias(true);
898 ++numResolvedAliases;
899 continue;
900 }
901
902 // restore
903 alias->setIdIndex(idIndex);
904 // Try again later and resolve the target alias first.
905 break;
906 }
907 }
908
909 if (!targetProperty || targetProperty->coreIndex() > 0x0000FFFF) {
911 alias->referenceLocation,
912 tr("Invalid alias target location: %1").arg(property.toString()));
913 break;
914 }
915
916 propIdx = QQmlPropertyIndex(targetProperty->coreIndex());
917
918 if (!subProperty.isEmpty()) {
919 const QMetaObject *valueTypeMetaObject = QQmlMetaType::metaObjectForValueType(targetProperty->propType());
920 if (!valueTypeMetaObject) {
921 // could be a deep alias
922 bool isDeepAlias = subProperty.at(0).isLower();
923 if (isDeepAlias) {
924 isDeepAlias = false;
925 for (auto it = targetObject->bindingsBegin(); it != targetObject->bindingsEnd(); ++it) {
926 auto binding = *it;
927 if (m_compiler->stringAt(binding.propertyNameIndex) == property) {
928 resolver = QQmlPropertyResolver(m_propertyCaches->at(binding.value.objectIndex));
929 const QQmlPropertyData *actualProperty = resolver.property(subProperty.toString());
930 if (actualProperty) {
931 propIdx = QQmlPropertyIndex(propIdx.coreIndex(), actualProperty->coreIndex());
932 isDeepAlias = true;
933 }
934 }
935 }
936 }
937 if (!isDeepAlias) {
939 alias->referenceLocation,
940 tr("Invalid alias target location: %1").arg(subProperty.toString()));
941 break;
942 }
943 } else {
944
945 int valueTypeIndex =
946 valueTypeMetaObject->indexOfProperty(subProperty.toString().toUtf8().constData());
947 if (valueTypeIndex == -1) {
949 alias->referenceLocation,
950 tr("Invalid alias target location: %1").arg(subProperty.toString()));
951 break;
952 }
953 Q_ASSERT(valueTypeIndex <= 0x0000FFFF);
954
955 propIdx = QQmlPropertyIndex(propIdx.coreIndex(), valueTypeIndex);
956 }
957 } else {
958 if (targetProperty->isQObject())
960 }
961 }
962
963 alias->encodedMetaPropertyIndex = propIdx.toEncoded();
965 numResolvedAliases++;
966 }
967
968 if (numResolvedAliases == 0)
969 return seenUnresolvedAlias ? NoAliasResolved : AllAliasesResolved;
970
971 return SomeAliasesResolved;
972}
973
975 : QQmlCompilePass(typeCompiler)
976 , qmlObjects(typeCompiler->qmlObjects())
977 , propertyCaches(typeCompiler->propertyCaches())
978 , customParsers(typeCompiler->customParserCache())
979 , _seenObjectWithId(false)
980{
981}
982
984{
985 for (int i = 0; i < qmlObjects->size(); ++i) {
986 if ((qmlObjects->at(i)->flags & QV4::CompiledData::Object::IsInlineComponentRoot)
987 && !scanObject(i, ScopeDeferred::False)) {
988 return false;
989 }
990 }
991 return scanObject(/*root object*/0, ScopeDeferred::False);
992}
993
995 int objectIndex, ScopeDeferred scopeDeferred)
996{
997 using namespace QV4::CompiledData;
998
999 QmlIR::Object *obj = qmlObjects->at(objectIndex);
1000 if (obj->idNameIndex != 0)
1001 _seenObjectWithId = true;
1002
1003 if (obj->flags & Object::IsComponent) {
1004 Q_ASSERT(obj->bindingCount() == 1);
1005 const Binding *componentBinding = obj->firstBinding();
1006 Q_ASSERT(componentBinding->type() == Binding::Type_Object);
1007 // Components are separate from their surrounding scope. They cannot be deferred.
1008 return scanObject(componentBinding->value.objectIndex, ScopeDeferred::False);
1009 }
1010
1011 QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(objectIndex);
1012 if (!propertyCache)
1013 return true;
1014
1015 QString defaultPropertyName;
1016 const QQmlPropertyData *defaultProperty = nullptr;
1017 if (obj->indexOfDefaultPropertyOrAlias != -1) {
1018 const QQmlPropertyCache *cache = propertyCache->parent().data();
1019 defaultPropertyName = cache->defaultPropertyName();
1020 defaultProperty = cache->defaultProperty();
1021 } else {
1022 defaultPropertyName = propertyCache->defaultPropertyName();
1023 defaultProperty = propertyCache->defaultProperty();
1024 }
1025
1026 QQmlCustomParser *customParser = customParsers.value(obj->inheritedTypeNameIndex);
1027
1028 QQmlPropertyResolver propertyResolver(propertyCache);
1029
1030 QStringList deferredPropertyNames;
1031 QStringList immediatePropertyNames;
1032 {
1033 const QMetaObject *mo = propertyCache->firstCppMetaObject();
1034 const int deferredNamesIndex = mo->indexOfClassInfo("DeferredPropertyNames");
1035 const int immediateNamesIndex = mo->indexOfClassInfo("ImmediatePropertyNames");
1036 if (deferredNamesIndex != -1) {
1037 if (immediateNamesIndex != -1) {
1038 COMPILE_EXCEPTION(obj, tr("You cannot define both DeferredPropertyNames and "
1039 "ImmediatePropertyNames on the same type."));
1040 }
1041 const QMetaClassInfo classInfo = mo->classInfo(deferredNamesIndex);
1042 deferredPropertyNames = QString::fromUtf8(classInfo.value()).split(u',');
1043 } else if (immediateNamesIndex != -1) {
1044 const QMetaClassInfo classInfo = mo->classInfo(immediateNamesIndex);
1045 immediatePropertyNames = QString::fromUtf8(classInfo.value()).split(u',');
1046
1047 // If the property contains an empty string, all properties shall be deferred.
1048 if (immediatePropertyNames.isEmpty())
1049 immediatePropertyNames.append(QString());
1050 }
1051 }
1052
1053 for (QmlIR::Binding *binding = obj->firstBinding(); binding; binding = binding->next) {
1054 QString name = stringAt(binding->propertyNameIndex);
1055
1056 if (customParser) {
1057 if (binding->type() == Binding::Type_AttachedProperty) {
1058 if (customParser->flags() & QQmlCustomParser::AcceptsAttachedProperties) {
1059 binding->setFlag(Binding::IsCustomParserBinding);
1060 obj->flags |= Object::HasCustomParserBindings;
1061 continue;
1062 }
1064 && !(customParser->flags() & QQmlCustomParser::AcceptsSignalHandlers)) {
1065 obj->flags |= Object::HasCustomParserBindings;
1066 binding->setFlag(Binding::IsCustomParserBinding);
1067 continue;
1068 }
1069 }
1070
1071 const bool hasPropertyData = [&]() {
1072 if (name.isEmpty()) {
1073 name = defaultPropertyName;
1074 if (defaultProperty)
1075 return true;
1076 } else if (name.constData()->isUpper()) {
1077 // Upper case names cannot be custom-parsed unless they are attached properties
1078 // and the custom parser explicitly accepts them. See above for that case.
1079 return false;
1080 } else {
1081 bool notInRevision = false;
1082 if (propertyResolver.property(
1083 name, &notInRevision, QQmlPropertyResolver::CheckRevision)) {
1084 return true;
1085 }
1086 }
1087
1088 if (!customParser)
1089 return false;
1090
1091 const Binding::Flags bindingFlags = binding->flags();
1092 if (bindingFlags & Binding::IsSignalHandlerExpression
1093 || bindingFlags & Binding::IsSignalHandlerObject
1094 || bindingFlags & Binding::IsPropertyObserver) {
1095 // These signal handlers cannot be custom-parsed. We have already established
1096 // that the signal exists.
1097 return false;
1098 }
1099
1100 // If the property isn't found, we may want to custom-parse the binding.
1101 obj->flags |= Object::HasCustomParserBindings;
1102 binding->setFlag(Binding::IsCustomParserBinding);
1103 return false;
1104 }();
1105
1106 bool seenSubObjectWithId = false;
1107 bool isExternal = false;
1108 if (binding->type() >= Binding::Type_Object) {
1109 const bool isOwnProperty = hasPropertyData || binding->isAttachedProperty();
1110 isExternal = !isOwnProperty && binding->isGroupProperty();
1111 if (isOwnProperty || isExternal) {
1112 qSwap(_seenObjectWithId, seenSubObjectWithId);
1113 const bool subObjectValid = scanObject(
1114 binding->value.objectIndex,
1115 (isExternal || scopeDeferred == ScopeDeferred::True)
1116 ? ScopeDeferred::True
1117 : ScopeDeferred::False);
1118 qSwap(_seenObjectWithId, seenSubObjectWithId);
1119 if (!subObjectValid)
1120 return false;
1121 _seenObjectWithId |= seenSubObjectWithId;
1122 }
1123 }
1124
1125 bool isDeferred = false;
1126 if (!immediatePropertyNames.isEmpty() && !immediatePropertyNames.contains(name)) {
1127 if (seenSubObjectWithId) {
1128 COMPILE_EXCEPTION(binding, tr("You cannot assign an id to an object assigned "
1129 "to a deferred property."));
1130 }
1131 if (isExternal || !disableInternalDeferredProperties())
1132 isDeferred = true;
1133 } else if (!deferredPropertyNames.isEmpty() && deferredPropertyNames.contains(name)) {
1134 if (!seenSubObjectWithId && binding->type() != Binding::Type_GroupProperty) {
1135 if (isExternal || !disableInternalDeferredProperties())
1136 isDeferred = true;
1137 }
1138 }
1139
1140 if (binding->type() >= Binding::Type_Object) {
1141 if (isExternal && !isDeferred && !customParser) {
1143 binding, tr("Cannot assign to non-existent property \"%1\"").arg(name));
1144 }
1145 }
1146
1147 if (isDeferred) {
1148 binding->setFlag(Binding::IsDeferredBinding);
1149 obj->flags |= Object::HasDeferredBindings;
1150 }
1151 }
1152
1153 return true;
1154}
1155
1157 : QQmlCompilePass(typeCompiler)
1158 , qmlObjects(*typeCompiler->qmlObjects())
1159 , propertyCaches(typeCompiler->propertyCaches())
1160{
1161
1162}
1163
1165{
1166 for (int i = 0; i < qmlObjects.size(); ++i)
1168}
1169
1171{
1172 QQmlPropertyCache::ConstPtr propertyCache = propertyCaches->at(objectIndex);
1173 if (!propertyCache)
1174 return;
1175
1176 QmlIR::Object *object = qmlObjects.at(objectIndex);
1177
1178 QString defaultProperty = object->indexOfDefaultPropertyOrAlias != -1 ? propertyCache->parent()->defaultPropertyName() : propertyCache->defaultPropertyName();
1179 QmlIR::Binding *bindingsToReinsert = nullptr;
1180 QmlIR::Binding *tail = nullptr;
1181
1182 QmlIR::Binding *previousBinding = nullptr;
1183 QmlIR::Binding *binding = object->firstBinding();
1184 while (binding) {
1185 if (binding->propertyNameIndex == quint32(0) || stringAt(binding->propertyNameIndex) != defaultProperty) {
1186 previousBinding = binding;
1187 binding = binding->next;
1188 continue;
1189 }
1190
1191 QmlIR::Binding *toReinsert = binding;
1192 binding = object->unlinkBinding(previousBinding, binding);
1193
1194 if (!tail) {
1195 bindingsToReinsert = toReinsert;
1196 tail = toReinsert;
1197 } else {
1198 tail->next = toReinsert;
1199 tail = tail->next;
1200 }
1201 tail->next = nullptr;
1202 }
1203
1204 binding = bindingsToReinsert;
1205 while (binding) {
1206 QmlIR::Binding *toReinsert = binding;
1207 binding = binding->next;
1208 object->insertSorted(toReinsert);
1209 }
1210}
1211
\inmodule QtCore
Definition qbytearray.h:57
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
Definition qbytearray.h:124
\inmodule QtCore
\inmodule QtCore
Definition qhash.h:1145
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
Definition qhash.h:1219
const_iterator constBegin() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the first item in the hash.
Definition qhash.h:1215
bool contains(const Key &key) const noexcept
Returns true if the hash contains an item with the key; otherwise returns false.
Definition qhash.h:1007
T value(const Key &key) const noexcept
Definition qhash.h:1054
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
Definition qhash.h:1303
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
const_reference at(qsizetype i) const noexcept
Definition qlist.h:446
void append(parameter_type t)
Definition qlist.h:458
void clear()
Definition qlist.h:434
\inmodule QtCore
\inmodule QtCore
int keysToValue(const char *keys, bool *ok=nullptr) const
Returns the value derived from combining together the values of the keys using the OR operator,...
bool isScoped() const
int keyToValue(const char *key, bool *ok=nullptr) const
Returns the integer value of the given enumeration key, or -1 if key is not defined.
const char * scope() const
Returns the scope this enumerator was declared in.
\inmodule QtCore
\inmodule QtCore
Definition qmetatype.h:341
int id(int=0) const
Definition qmetatype.h:475
QQmlAliasAnnotator(QQmlTypeCompiler *typeCompiler)
QQmlCustomParserScriptIndexer(QQmlTypeCompiler *typeCompiler)
The QQmlCustomParser class allows you to add new arbitrary types to QML.
QString finalUrlString() const
Returns the finalUrl() as a string.
QString urlString() const
QQmlDefaultPropertyMerger(QQmlTypeCompiler *typeCompiler)
QQmlDeferredAndCustomParserBindingScanner(QQmlTypeCompiler *typeCompiler)
QV4::ExecutionEngine * v4engine() const
QQmlEnumTypeResolver(QQmlTypeCompiler *typeCompiler)
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
The QQmlImports class encapsulates one QML document's import statements.
bool resolveType(QQmlTypeLoader *typeLoader, const QHashedStringRef &type, QQmlType *type_return, QTypeRevision *version_return, QQmlImportNamespace **ns_return, QList< QQmlError > *errors=nullptr, QQmlType::RegistrationType registrationType=QQmlType::AnyRegistrationType, bool *typeRecursionDetected=nullptr) const
MemoryPool * pool()
QStringView newStringRef(const QString &text)
static const QMetaObject * metaObjectForValueType(QMetaType type)
static QQmlPropertyCache::ConstPtr propertyCache(QObject *object, QTypeRevision version=QTypeRevision())
Returns a QQmlPropertyCache for obj if one is available.
static QQmlType qmlType(const QString &qualifiedName, QTypeRevision version)
Returns the type (if any) of URI-qualified named qualifiedName and version specified by version_major...
QQmlPropertyCache::ConstPtr at(int index) const
QMetaType propType() const
T * data() const
QQmlScriptStringScanner(QQmlTypeCompiler *typeCompiler)
static std::optional< QString > changedHandlerNameToSignalName(QStringView changedHandler)
static std::optional< QString > changedHandlerNameToPropertyName(QStringView handler)
static bool isHandlerName(QStringView signalName)
static std::optional< QString > handlerNameToSignalName(QStringView handler)
QQmlType qmlType(const QString &inlineComponentName=QString()) const
QByteArray typeClassName() const
const QQmlImports * imports() const
static QQmlTypeLoader * get(Engine *engine)
QTypeRevision version() const
Definition qqmltype.cpp:112
QHashedString module() const
Definition qqmltype.cpp:105
bool isValid() const
Definition qqmltype_p.h:54
QString elementName() const
Definition qqmltype.cpp:462
bool contains(const T &value) const
Definition qset.h:71
\inmodule QtCore
\inmodule QtCore
Definition qstringview.h:78
constexpr bool isEmpty() const noexcept
Returns whether this string view is empty - that is, whether {size() == 0}.
constexpr QStringView left(qsizetype n) const noexcept
constexpr QStringView mid(qsizetype pos, qsizetype n=-1) const noexcept
Returns the substring of length length starting at position start in this object.
qsizetype indexOf(QChar c, qsizetype from=0, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
const QChar * constData() const
Returns a pointer to the data stored in the QString.
Definition qstring.h:1246
qsizetype size() const noexcept
Returns the number of characters in this string.
Definition qstring.h:186
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:6018
QByteArray toUtf8() const &
Definition qstring.h:634
\inmodule QtCore
static constexpr QTypeRevision fromVersion(Major majorVersion, Minor minorVersion)
Produces a QTypeRevision from the given majorVersion and minorVersion, both of which need to be a val...
QString str
[2]
QCache< int, Employee > cache
[0]
QSet< QString >::iterator it
auto signal
auto mo
[7]
const char * classInfo(const QMetaObject *metaObject, const char *key)
Combined button and popup list for selecting options.
std::function< QByteArray()> DependentTypesHasher
quint64 ReturnedValue
Q_CORE_EXPORT Q_DECL_PURE_FUNCTION bool isUpper(QStringView s) noexcept
Definition qstring.cpp:5562
QString enumValue(const QString &value)
Definition language.cpp:506
QString qualifier
Definition language.cpp:57
QList< QString > QStringList
Constructs a string list that contains the given string, str.
DBusConnection const char DBusError * error
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
#define Q_LOGGING_CATEGORY(name,...)
const char * typeName
GLint location
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLuint GLuint end
GLenum GLenum GLsizei count
GLenum type
GLuint GLsizei const GLchar * message
GLenum const GLint * param
GLuint name
GLhandleARB obj
[2]
const GLubyte * c
GLhandleARB attachedObj
GLuint entry
GLuint64EXT * result
[6]
GLsizei const GLchar *const * string
[0]
Definition qopenglext.h:694
static qreal dot(const QPointF &a, const QPointF &b)
static qreal component(const QPointF &point, unsigned int i)
#define DEFINE_BOOL_CONFIG_OPTION(name, var)
#define COMPILE_EXCEPTION(location, desc)
QT_BEGIN_NAMESPACE QQmlError qQmlCompileError(const QV4::CompiledData::Location &location, const QString &description)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
#define Q_ASSERT_X(cond, x, msg)
Definition qrandom.cpp:48
SSL_CTX int void * arg
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define QStringLiteral(str)
QT_BEGIN_NAMESPACE constexpr void qSwap(T &value1, T &value2) noexcept(std::is_nothrow_swappable_v< T >)
Definition qswap.h:20
#define tr(X)
#define Q_UNUSED(x)
unsigned int quint32
Definition qtypes.h:50
const char property[13]
Definition qwizard.cpp:101
if(qFloatDistance(a, b)<(1<< 7))
[0]
QByteArray ba
[0]
obj metaObject() -> className()
list indexOf("B")
QAction * at
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
\inmodule QtCore
QQmlCompilePass(QQmlTypeCompiler *typeCompiler)
QV4::ResolvedTypeReference * resolvedType(int id) const
QQmlTypeCompiler * compiler
QString stringAt(int idx) const
void resolveMissingPropertyCaches(QQmlPropertyCacheVector *propertyCaches) const
const QQmlPropertyData * property(int index) const
QQmlEnginePrivate * enginePrivate() const
int registerConstant(QV4::ReturnedValue v)
QQmlTypeCompiler(QQmlEnginePrivate *engine, QQmlTypeData *typeData, QmlIR::Document *document, QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache, const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
QV4::CompiledData::ResolvedTypeReferenceMap * resolvedTypes
const QV4::CompiledData::Unit * qmlUnit() const
QQmlType qmlTypeForComponent(const QString &inlineComponentName=QString()) const
QQmlPropertyCacheVector * propertyCaches()
QQmlJS::MemoryPool * memoryPool()
QString bindingAsString(const QmlIR::Object *object, int scriptIndex) const
int registerString(const QString &str)
const QV4::Compiler::StringTableGenerator * stringPool() const
void recordError(const QV4::CompiledData::Location &location, const QString &description)
QStringView newStringRef(const QString &string)
void addImport(const QString &module, const QString &qualifier, QTypeRevision version)
QQmlRefPointer< QV4::CompiledData::CompilationUnit > compile()
QVector< QmlIR::Object * > * qmlObjects() const
QString stringAt(int idx) const
const QQmlImports * imports() const
bool hasFlag(Flag flag) const
union QV4::CompiledData::Binding::@545 value
StringTableGenerator stringTable
int registerConstant(ReturnedValue v)
int registerString(const QString &str)
const QSet< QString > & illegalNames() const
QQmlRefPointer< QV4::CompiledData::CompilationUnit > javaScriptCompilationUnit
QVector< Object * > objects
QString stringAt(int index) const
QV4::Compiler::Module jsModule
QV4::Compiler::JSUnitGenerator jsGenerator
QList< const QV4::CompiledData::Import * > imports
QQmlJS::Engine jsParserEngine
PoolList< Binding >::Iterator bindingsEnd() const
PoolList< Alias >::Iterator aliasesBegin() const
void init(QQmlJS::MemoryPool *pool, int typeNameIndex, int idIndex, const QV4::CompiledData::Location &location)
PoolList< Binding >::Iterator bindingsBegin() const
PoolList< Alias >::Iterator aliasesEnd() const
void generate(Document &output, const QV4::CompiledData::DependentTypesHasher &dependencyHasher=QV4::CompiledData::DependentTypesHasher())
SignalHandlerResolver(QQmlTypeCompiler *typeCompiler)