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
qqmltypedata.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
4#include <private/qqmlcomponentandaliasresolver_p.h>
5#include <private/qqmlengine_p.h>
6#include <private/qqmlirbuilder_p.h>
7#include <private/qqmlirloader_p.h>
8#include <private/qqmlpropertycachecreator_p.h>
9#include <private/qqmlpropertyvalidator_p.h>
10#include <private/qqmlscriptblob_p.h>
11#include <private/qqmlscriptdata_p.h>
12#include <private/qqmltypecompiler_p.h>
13#include <private/qqmltypedata_p.h>
14#include <private/qqmltypeloaderqmldircontent_p.h>
15
16#include <QtCore/qloggingcategory.h>
17#include <QtCore/qcryptographichash.h>
18
19#include <memory>
20
21Q_DECLARE_LOGGING_CATEGORY(DBG_DISK_CACHE)
22Q_LOGGING_CATEGORY(lcCycle, "qt.qml.typeresolution.cycle", QtWarningMsg)
23
25
29
31{
33 if (!prefix.isEmpty()) {
34 result = prefix + QLatin1Char('.');
35 }
36 result.append(type.qmlTypeName());
37 return result;
38}
39
40QQmlTypeData::QQmlTypeData(const QUrl &url, QQmlTypeLoader *manager)
42 m_typesResolved(false), m_implicitImportLoaded(false)
43{
44
45}
46
48{
49 m_scripts.clear();
50 m_compositeSingletons.clear();
51 m_resolvedTypes.clear();
52}
53
55{
56 return m_compiledData.data();
57}
58
60{
61 Q_ASSERT(!m_callbacks.contains(callback));
62 m_callbacks.append(callback);
63}
64
66{
67 Q_ASSERT(m_callbacks.contains(callback));
68 m_callbacks.removeOne(callback);
69 Q_ASSERT(!m_callbacks.contains(callback));
70}
71
72QQmlType QQmlTypeData::qmlType(const QString &inlineComponentName) const
73{
74 if (inlineComponentName.isEmpty())
75 return m_qmlType;
76 return m_inlineComponentData[inlineComponentName].qmlType;
77}
78
79bool QQmlTypeData::tryLoadFromDiskCache()
80{
81 if (!readCacheFile())
82 return false;
83
84 auto unit = QQml::makeRefPointer<QV4::CompiledData::CompilationUnit>();
85 {
87 if (!unit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) {
88 qCDebug(DBG_DISK_CACHE) << "Error loading" << urlString() << "from disk cache:" << error;
89 return false;
90 }
91 }
92
93 if (unit->unitData()->flags & QV4::CompiledData::Unit::PendingTypeCompilation) {
94 restoreIR(unit);
95 return true;
96 }
97
98 m_compiledData = std::move(unit);
99
100 QVector<QV4::CompiledData::InlineComponent> ics;
101 for (int i = 0, count = m_compiledData->objectCount(); i < count; ++i) {
102 auto object = m_compiledData->objectAt(i);
103 m_typeReferences.collectFromObject(object);
104 const auto inlineComponentTable = object->inlineComponentTable();
105 for (auto i = 0; i != object->nInlineComponents; ++i) {
106 ics.push_back(inlineComponentTable[i]);
107 }
108 }
109
111
112 // For remote URLs, we don't delay the loading of the implicit import
113 // because the loading probably requires an asynchronous fetch of the
114 // qmldir (so we can't load it just in time).
115 if (!finalUrl().scheme().isEmpty()) {
116 QUrl qmldirUrl = finalUrl().resolved(QUrl(QLatin1String("qmldir")));
117 if (!QQmlImports::isLocal(qmldirUrl)) {
118 if (!loadImplicitImport())
119 return false;
120
121 // find the implicit import
122 for (quint32 i = 0, count = m_compiledData->importCount(); i < count; ++i) {
123 const QV4::CompiledData::Import *import = m_compiledData->importAt(i);
124 if (m_compiledData->stringAt(import->uriIndex) == QLatin1String(".")
125 && import->qualifierIndex == 0
126 && !import->version.hasMajorVersion()
127 && !import->version.hasMinorVersion()) {
128 QList<QQmlError> errors;
129 auto pendingImport = std::make_shared<PendingImport>(
130 this, import, QQmlImports::ImportNoFlag);
131 pendingImport->precedence = QQmlImportInstance::Implicit;
132 if (!fetchQmldir(qmldirUrl, pendingImport, 1, &errors)) {
134 return false;
135 }
136 break;
137 }
138 }
139 }
140 }
141
142 for (int i = 0, count = m_compiledData->importCount(); i < count; ++i) {
143 const QV4::CompiledData::Import *import = m_compiledData->importAt(i);
144 QList<QQmlError> errors;
145 if (!addImport(import, {}, &errors)) {
148 error.setUrl(m_importCache->baseUrl());
149 error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line()));
150 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column()));
151 errors.prepend(error); // put it back on the list after filling out information.
153 return false;
154 }
155 }
156
157 for (auto&& ic: ics) {
158 QString const nameString = m_compiledData->stringAt(ic.nameIndex);
159 auto importUrl = finalUrl();
160 importUrl.setFragment(nameString);
161 auto import = new QQmlImportInstance();
162 m_importCache->addInlineComponentImport(import, nameString, importUrl);
163 }
164
165 return true;
166}
167
168template<>
170 const QV4::CompiledData::Object *object) const
171{
172 Q_UNUSED(object);
173}
174
175template<>
177{
178 return m_compiler->objectAt(index)->hasFlag(QV4::CompiledData::Object::IsComponent);
179}
180
181template<>
183{
185 // we cannot sanity-check the index here because bindings are sorted in a different order
186 // in the CU vs the IR.
187}
188
189template<>
191 const CompiledObject &component, CompiledBinding *binding)
192{
193 // We cannot make it fail here. It might be a custom-parsed property
194 for (int i = 0, count = component.namedObjectsInComponentCount(); i < count; ++i) {
195 const int candidateIndex = component.namedObjectsInComponentTable()[i];
196 if (m_compiler->objectAt(candidateIndex)->idNameIndex == binding->propertyNameIndex) {
197 m_propertyCaches->set(binding->value.objectIndex, m_propertyCaches->at(candidateIndex));
198 return;
199 }
200 }
201}
202
203template<>
204typename QQmlComponentAndAliasResolver<QV4::CompiledData::CompilationUnit>::AliasResolutionResult
206 const CompiledObject &component, int objectIndex, QQmlError *error)
207{
208 const CompiledObject *obj = m_compiler->objectAt(objectIndex);
209 for (auto alias = obj->aliasesBegin(), end = obj->aliasesEnd(); alias != end; ++alias) {
210 if (!alias->hasFlag(QV4::CompiledData::Alias::Resolved)) {
211 *error = qQmlCompileError( alias->referenceLocation, tr("Unresolved alias found"));
212 return NoAliasResolved;
213 }
214
215 if (alias->isAliasToLocalAlias() || alias->encodedMetaPropertyIndex == -1)
216 continue;
217
218 const int targetObjectIndex
219 = objectForId(m_compiler, component, alias->targetObjectId());
220 const int coreIndex
221 = QQmlPropertyIndex::fromEncoded(alias->encodedMetaPropertyIndex).coreIndex();
222
223 QQmlPropertyCache::ConstPtr targetCache = m_propertyCaches->at(targetObjectIndex);
224 Q_ASSERT(targetCache);
225
226 if (!targetCache->property(coreIndex))
227 return SomeAliasesResolved;
228 }
229
230 return AllAliasesResolved;
231}
232
233template<>
235 const QV4::CompiledData::Binding *binding)
236{
237 // This should have been done when creating the CU.
238 Q_UNUSED(binding);
239 return false;
240}
241
242QQmlError QQmlTypeData::createTypeAndPropertyCaches(
243 const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
244 const QV4::CompiledData::ResolvedTypeReferenceMap &resolvedTypeCache)
245{
246 Q_ASSERT(m_compiledData);
247 m_compiledData->typeNameCache = typeNameCache;
248 m_compiledData->resolvedTypes = resolvedTypeCache;
249 m_compiledData->inlineComponentData = m_inlineComponentData;
250
252
253 QQmlPendingGroupPropertyBindings pendingGroupPropertyBindings;
254
255 {
256 QQmlPropertyCacheCreator<QV4::CompiledData::CompilationUnit> propertyCacheCreator(
257 &m_compiledData->propertyCaches, &pendingGroupPropertyBindings, engine,
258 m_compiledData.data(), m_importCache.data(), typeClassName());
259
260 QQmlError error = propertyCacheCreator.verifyNoICCycle();
261 if (error.isValid())
262 return error;
263
265 do {
266 result = propertyCacheCreator.buildMetaObjectsIncrementally();
267 if (result.error.isValid()) {
268 return result.error;
269 } else {
271 m_compiledData.data(), engine, &m_compiledData->propertyCaches);
272 if (const QQmlError error = resolver.resolve(result.processedRoot);
273 error.isValid()) {
274 return error;
275 }
276 pendingGroupPropertyBindings.resolveMissingPropertyCaches(
277 &m_compiledData->propertyCaches);
278 pendingGroupPropertyBindings.clear(); // anything that can be processed is now processed
279 }
280
281 } while (result.canResume);
282 }
283
284 pendingGroupPropertyBindings.resolveMissingPropertyCaches(&m_compiledData->propertyCaches);
285 return QQmlError();
286}
287
289 const QList<QQmlTypeData::TypeReference> &typeRefs,
290 QHash<quintptr, QByteArray> *checksums, QCryptographicHash *hash)
291{
292 for (const auto &typeRef: typeRefs) {
293 if (typeRef.typeData) {
294 const auto unit = typeRef.typeData->compilationUnit()->unitData();
295 hash->addData({unit->md5Checksum, sizeof(unit->md5Checksum)});
296 } else if (const QMetaObject *mo = typeRef.type.metaObject()) {
297 const auto propertyCache = QQmlMetaType::propertyCache(mo);
298 bool ok = false;
299 hash->addData(propertyCache->checksum(checksums, &ok));
300 if (!ok)
301 return false;
302 }
303 }
304 return true;
305}
306
307// local helper function for inline components
308namespace {
309using InlineComponentData = QV4::CompiledData::InlineComponentData;
310
311template<typename ObjectContainer>
312void setupICs(
313 const ObjectContainer &container, QHash<QString, InlineComponentData> *icData,
314 const QUrl &baseUrl,
315 const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &compilationUnit) {
316 Q_ASSERT(icData->empty());
317 for (int i = 0; i != container->objectCount(); ++i) {
318 auto root = container->objectAt(i);
319 for (auto it = root->inlineComponentsBegin(); it != root->inlineComponentsEnd(); ++it) {
320 // We cannot re-use a previously finalized inline component type here. We need our own.
321 // We can and should re-use speculative type references, though.
322 InlineComponentData icDatum(
324 baseUrl, container->stringAt(it->nameIndex), compilationUnit),
325 int(it->objectIndex), int(it->nameIndex), 0, 0, 0);
326
327 icData->insert(container->stringAt(it->nameIndex), icDatum);
328 }
329 }
330};
331}
332
333template<typename Container>
334void QQmlTypeData::setCompileUnit(const Container &container)
335{
336 for (int i = 0; i != container->objectCount(); ++i) {
337 auto const root = container->objectAt(i);
338 for (auto it = root->inlineComponentsBegin(); it != root->inlineComponentsEnd(); ++it) {
339 auto *typeRef = m_compiledData->resolvedType(it->nameIndex);
340
341 // We don't want the type reference to keep a strong reference to the compilation unit
342 // here. The compilation unit owns the type reference, and having a strong reference
343 // would prevent the compilation unit from ever getting deleted. We can still be sure
344 // that the compilation unit outlives the type reference, due to ownership.
345 typeRef->setReferencesCompilationUnit(false);
346
347 typeRef->setCompilationUnit(m_compiledData); // share compilation unit
348 }
349 }
350}
351
353{
354 auto cleanup = qScopeGuard([this]{
355 m_backupSourceCode = SourceCodeData();
356 m_document.reset();
357 m_typeReferences.clear();
358 if (isError()) {
359 const auto encounteredErrors = errors();
360 for (const QQmlError &e : encounteredErrors)
361 qCDebug(DBG_DISK_CACHE) << e.toString();
362 m_compiledData.reset();
363 }
364 });
365
366 if (isError())
367 return;
368
369 // Check all script dependencies for errors
370 for (int ii = 0; ii < m_scripts.size(); ++ii) {
371 const ScriptReference &script = m_scripts.at(ii);
373 if (script.script->isError()) {
374 QList<QQmlError> errors = script.script->errors();
376 error.setUrl(url());
377 error.setLine(qmlConvertSourceCoordinate<quint32, int>(script.location.line()));
378 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(script.location.column()));
379 error.setDescription(QQmlTypeLoader::tr("Script %1 unavailable").arg(script.script->urlString()));
382 return;
383 }
384 }
385
386 // Check all type dependencies for errors
387 auto createError = [&](const TypeReference &type , const QString &message) {
388 QList<QQmlError> errors = type.typeData ? type.typeData->errors() : QList<QQmlError>{};
390 error.setUrl(url());
391 error.setLine(qmlConvertSourceCoordinate<quint32, int>(type.location.line()));
392 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(type.location.column()));
393 error.setDescription(message);
396 };
397 for (auto it = std::as_const(m_resolvedTypes).begin(), end = std::as_const(m_resolvedTypes).end(); it != end;
398 ++it) {
399 const TypeReference &type = *it;
400 Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError() || type.type.isInlineComponentType());
401
402 if (type.type.isInlineComponentType()) {
403 const QUrl url = type.type.sourceUrl();
405 && !QQmlMetaType::obtainCompilationUnit(type.type.typeId())) {
406 const QString &typeName = stringAt(it.key());
407 int lastDot = typeName.lastIndexOf(u'.');
408 createError(
409 type,
410 QQmlTypeLoader::tr("Type %1 has no inline component type called %2")
411 .arg(QStringView{typeName}.left(lastDot), type.type.elementName()));
412 return;
413 }
414 }
415 if (type.typeData && type.typeData->isError()) {
416 const QString &typeName = stringAt(it.key());
417 createError(type, QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName));
418 return;
419 }
420 }
421
422 // Check all composite singleton type dependencies for errors
423 for (int ii = 0; ii < m_compositeSingletons.size(); ++ii) {
424 const TypeReference &type = m_compositeSingletons.at(ii);
425 Q_ASSERT(!type.typeData || type.typeData->isCompleteOrError());
426 if (type.typeData && type.typeData->isError()) {
427 QString typeName = type.type.qmlTypeName();
428
429 createError(type, QQmlTypeLoader::tr("Type %1 unavailable").arg(typeName));
430 return;
431 }
432 }
433
435 const bool isSingleton = m_document
436 ? m_document.data()->isSingleton()
437 : (m_compiledData->unitData()->flags & QV4::CompiledData::Unit::IsSingleton);
439 finalUrl(), m_compiledData, isSingleton
442 m_typeClassName = QByteArray(m_qmlType.typeId().name()).chopped(1);
443 }
444
445 if (m_document)
446 setupICs(m_document, &m_inlineComponentData, finalUrl(), m_compiledData);
447 else
448 setupICs(m_compiledData, &m_inlineComponentData, finalUrl(), m_compiledData);
449
451 QQmlRefPointer<QQmlTypeNameCache> typeNameCache;
452 {
453 QQmlError error = buildTypeResolutionCaches(&typeNameCache, &resolvedTypeCache);
454 if (error.isValid()) {
456 qDeleteAll(resolvedTypeCache);
457 return;
458 }
459 }
460
461 const auto dependencyHasher = [&resolvedTypeCache, this]() {
463 return (resolvedTypeCache.addToHash(&hash, typeLoader()->checksumCache())
465 m_compositeSingletons, typeLoader()->checksumCache(), &hash))
466 ? hash.result()
467 : QByteArray();
468 };
469
470 // verify if any dependencies changed if we're using a cache
471 if (m_document.isNull()) {
472 const QQmlError error = createTypeAndPropertyCaches(typeNameCache, resolvedTypeCache);
473 if (!error.isValid() && m_compiledData->verifyChecksum(dependencyHasher)) {
474 setCompileUnit(m_compiledData);
475 } else {
476
477 if (error.isValid()) {
478 qCDebug(DBG_DISK_CACHE)
479 << "Failed to create property caches for"
480 << m_compiledData->fileName()
481 << "because" << error.description();
482 } else {
483 qCDebug(DBG_DISK_CACHE)
484 << "Checksum mismatch for cached version of"
485 << m_compiledData->fileName();
486 }
487
488 if (!loadFromSource())
489 return;
490
491 // We want to keep our resolve types ...
492 m_compiledData->resolvedTypes.clear();
493 // ... but we don't want the property caches we've created for the broken CU.
494 for (QV4::ResolvedTypeReference *ref: std::as_const(resolvedTypeCache)) {
495 const auto compilationUnit = ref->compilationUnit();
496 if (compilationUnit.isNull()) {
497 // Inline component references without CU belong to the surrounding CU.
498 // We have to clear them. Inline component references to other documents
499 // have a CU.
500 if (!ref->type().isInlineComponentType())
501 continue;
502 } else if (compilationUnit != m_compiledData) {
503 continue;
504 }
505 ref->setTypePropertyCache(QQmlPropertyCache::ConstPtr());
506 ref->setCompilationUnit(QQmlRefPointer<QV4::CompiledData::CompilationUnit>());
507 }
508
509 m_compiledData.reset();
510 }
511 }
512
513 if (!m_document.isNull()) {
514 // Compile component
515 compile(typeNameCache, &resolvedTypeCache, dependencyHasher);
516 if (isError())
517 return;
518 else
519 setCompileUnit(m_document);
520 }
521
522 {
523 QQmlEnginePrivate *const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine());
524 m_compiledData->inlineComponentData = m_inlineComponentData;
525 {
526 // Sanity check property bindings
527 QQmlPropertyValidator validator(enginePrivate, m_importCache.data(), m_compiledData);
528 QVector<QQmlError> errors = validator.validate();
529 if (!errors.isEmpty()) {
531 return;
532 }
533 }
534
535 m_compiledData->finalizeCompositeType(qmlType());
536 }
537
538 {
540 if (m_compiledData && m_compiledData->unitData()->flags & QV4::CompiledData::Unit::IsSingleton) {
541 if (!type.isValid()) {
543 error.setDescription(QQmlTypeLoader::tr("No matching type found, pragma Singleton files cannot be used by QQmlComponent."));
545 return;
546 } else if (!type.isCompositeSingleton()) {
548 error.setDescription(QQmlTypeLoader::tr("pragma Singleton used with a non composite singleton type %1").arg(type.qmlTypeName()));
550 return;
551 }
552 } else {
553 // If the type is CompositeSingleton but there was no pragma Singleton in the
554 // QML file, lets report an error.
555 if (type.isValid() && type.isCompositeSingleton()) {
556 QString typeName = type.qmlTypeName();
557 setError(QQmlTypeLoader::tr("qmldir defines type as singleton, but no pragma Singleton found in type %1.").arg(typeName));
558 return;
559 }
560 }
561 }
562
563 {
564 // Collect imported scripts
565 m_compiledData->dependentScripts.reserve(m_scripts.size());
566 for (int scriptIndex = 0; scriptIndex < m_scripts.size(); ++scriptIndex) {
567 const QQmlTypeData::ScriptReference &script = m_scripts.at(scriptIndex);
568
569 QStringView qualifier(script.qualifier);
570 QString enclosingNamespace;
571
572 const int lastDotIndex = qualifier.lastIndexOf(QLatin1Char('.'));
573 if (lastDotIndex != -1) {
574 enclosingNamespace = qualifier.left(lastDotIndex).toString();
575 qualifier = qualifier.mid(lastDotIndex+1);
576 }
577
578 m_compiledData->typeNameCache->add(
579 qualifier.toString(), scriptIndex, enclosingNamespace);
580 QQmlRefPointer<QQmlScriptData> scriptData = script.script->scriptData();
581 m_compiledData->dependentScripts << scriptData;
582 }
583 }
584}
585
587{
588 // Notify callbacks
589 while (!m_callbacks.isEmpty()) {
590 TypeDataCallback *callback = m_callbacks.takeFirst();
591 callback->typeDataReady(this);
592 }
593}
594
595bool QQmlTypeData::loadImplicitImport()
596{
597 m_implicitImportLoaded = true; // Even if we hit an error, count as loaded (we'd just keep hitting the error)
598
600
601 // For local urls, add an implicit import "." as most overridden lookup.
602 // This will also trigger the loading of the qmldir and the import of any native
603 // types from available plugins.
604 QList<QQmlError> implicitImportErrors;
605 QString localQmldir;
606 m_importCache->addImplicitImport(typeLoader(), &localQmldir, &implicitImportErrors);
607
608 // When loading with QQmlImports::ImportImplicit, the imports are _appended_ to the namespace
609 // in the order they are loaded. Therefore, the addImplicitImport above gets the highest
610 // precedence. This is in contrast to normal priority imports. Those are _prepended_ in the
611 // order they are loaded.
612 if (!localQmldir.isEmpty()) {
613 const QQmlTypeLoaderQmldirContent qmldir = typeLoader()->qmldirContent(localQmldir);
614 const QList<QQmlDirParser::Import> moduleImports
616 + qmldir.imports();
617 loadDependentImports(moduleImports, QString(), QTypeRevision(),
619 &implicitImportErrors);
620 }
621
622 if (!implicitImportErrors.isEmpty()) {
623 setError(implicitImportErrors);
624 return false;
625 }
626
627 return true;
628}
629
631{
632 m_backupSourceCode = data;
633
634 if (tryLoadFromDiskCache())
635 return;
636
637 if (isError())
638 return;
639
640 if (!m_backupSourceCode.exists() || m_backupSourceCode.isEmpty()) {
642 setError(QQmlTypeLoader::tr("File was compiled ahead of time with an incompatible version of Qt and the original file cannot be found. Please recompile"));
643 else if (!m_backupSourceCode.exists())
644 setError(QQmlTypeLoader::tr("No such file or directory"));
645 else
646 setError(QQmlTypeLoader::tr("File is empty"));
647 return;
648 }
649
650 if (!loadFromSource())
651 return;
652
653 continueLoadFromIR();
654}
655
657{
658 m_document.reset(new QmlIR::Document(isDebugging()));
659 QQmlIRLoader loader(unit->qmlData, m_document.data());
660 loader.load();
661 m_document->jsModule.fileName = urlString();
662 m_document->jsModule.finalUrl = finalUrlString();
663 m_document->javaScriptCompilationUnit
664 = QQmlRefPointer<QV4::CompiledData::CompilationUnit>(
667 continueLoadFromIR();
668}
669
670bool QQmlTypeData::loadFromSource()
671{
672 m_document.reset(new QmlIR::Document(isDebugging()));
673 m_document->jsModule.sourceTimeStamp = m_backupSourceCode.sourceTimeStamp();
676
677 QString sourceError;
678 const QString source = m_backupSourceCode.readAll(&sourceError);
679 if (!sourceError.isEmpty()) {
680 setError(sourceError);
681 return false;
682 }
683
684 if (!compiler.generateFromQml(source, finalUrlString(), m_document.data())) {
685 QList<QQmlError> errors;
686 errors.reserve(compiler.errors.size());
687 for (const QQmlJS::DiagnosticMessage &msg : std::as_const(compiler.errors)) {
688 QQmlError e;
689 e.setUrl(url());
690 e.setLine(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startLine));
691 e.setColumn(qmlConvertSourceCoordinate<quint32, int>(msg.loc.startColumn));
692 e.setDescription(msg.message);
693 errors << e;
694 }
696 return false;
697 }
698 return true;
699}
700
701void QQmlTypeData::restoreIR(const QQmlRefPointer<QV4::CompiledData::CompilationUnit> &unit)
702{
703 m_document.reset(new QmlIR::Document(isDebugging()));
704 QQmlIRLoader loader(unit->unitData(), m_document.data());
705 loader.load();
706 m_document->jsModule.fileName = urlString();
707 m_document->jsModule.finalUrl = finalUrlString();
708 m_document->javaScriptCompilationUnit = unit;
709 continueLoadFromIR();
710}
711
712void QQmlTypeData::continueLoadFromIR()
713{
714 for (auto const& object: m_document->objects) {
715 for (auto it = object->inlineComponentsBegin(); it != object->inlineComponentsEnd(); ++it) {
716 QString const nameString = m_document->stringAt(it->nameIndex);
717 auto importUrl = finalUrl();
718 importUrl.setFragment(nameString);
719 auto import = new QQmlImportInstance(); // Note: The cache takes ownership of the QQmlImportInstance
720 m_importCache->addInlineComponentImport(import, nameString, importUrl);
721 }
722 }
723
724 m_typeReferences.collectFromObjects(m_document->objects.constBegin(), m_document->objects.constEnd());
726
727 // For remote URLs, we don't delay the loading of the implicit import
728 // because the loading probably requires an asynchronous fetch of the
729 // qmldir (so we can't load it just in time).
730 if (!finalUrl().scheme().isEmpty()) {
731 QUrl qmldirUrl = finalUrl().resolved(QUrl(QLatin1String("qmldir")));
732 if (!QQmlImports::isLocal(qmldirUrl)) {
733 if (!loadImplicitImport())
734 return;
735 // This qmldir is for the implicit import
736 auto implicitImport = std::make_shared<PendingImport>();
737 implicitImport->uri = QLatin1String(".");
738 implicitImport->version = QTypeRevision();
739 QList<QQmlError> errors;
740
741 if (!fetchQmldir(qmldirUrl, implicitImport, 1, &errors)) {
743 return;
744 }
745 }
746 }
747
748 QList<QQmlError> errors;
749
750 for (const QV4::CompiledData::Import *import : std::as_const(m_document->imports)) {
751 if (!addImport(import, {}, &errors)) {
753
754 // We're only interested in the chronoligically last error. The previous
755 // errors might be from unsuccessfully trying to load a module from the
756 // resource file system.
758 error.setUrl(m_importCache->baseUrl());
759 error.setLine(qmlConvertSourceCoordinate<quint32, int>(import->location.line()));
760 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(import->location.column()));
762 return;
763 }
764 }
765}
766
768{
770
771 if (!m_typesResolved) {
772 // Check that all imports were resolved
773 QList<QQmlError> errors;
774 auto it = m_unresolvedImports.constBegin(), end = m_unresolvedImports.constEnd();
775 for ( ; it != end; ++it) {
776 if ((*it)->priority == 0) {
777 // This import was not resolved
778 for (auto keyIt = m_unresolvedImports.constBegin(),
779 keyEnd = m_unresolvedImports.constEnd();
780 keyIt != keyEnd; ++keyIt) {
781 const PendingImportPtr &import = *keyIt;
783 error.setDescription(QQmlTypeLoader::tr("module \"%1\" is not installed").arg(import->uri));
784 error.setUrl(m_importCache->baseUrl());
785 error.setLine(qmlConvertSourceCoordinate<quint32, int>(
786 import->location.line()));
787 error.setColumn(qmlConvertSourceCoordinate<quint32, int>(
788 import->location.column()));
790 }
791 }
792 }
793 if (errors.size()) {
795 return;
796 }
797
798 resolveTypes();
799 m_typesResolved = true;
800 }
801}
802
804{
805 for (int ii = 0; ii < m_callbacks.size(); ++ii) {
806 TypeDataCallback *callback = m_callbacks.at(ii);
807 callback->typeDataProgress(this, p);
808 }
809}
810
812{
813 if (m_compiledData)
814 return m_compiledData->stringAt(index);
815 return m_document->jsGenerator.stringTable.stringForIndex(index);
816}
817
818void QQmlTypeData::compile(const QQmlRefPointer<QQmlTypeNameCache> &typeNameCache,
820 const QV4::CompiledData::DependentTypesHasher &dependencyHasher)
821{
822 Q_ASSERT(m_compiledData.isNull());
823
824 const bool typeRecompilation = m_document
825 && m_document->javaScriptCompilationUnit
826 && m_document->javaScriptCompilationUnit->unitData()
827 && (m_document->javaScriptCompilationUnit->unitData()->flags
829
830 QQmlEnginePrivate * const enginePrivate = QQmlEnginePrivate::get(typeLoader()->engine());
831 QQmlTypeCompiler compiler(
832 enginePrivate, this, m_document.data(), resolvedTypeCache, dependencyHasher);
833 auto compilationUnit = compiler.compile();
834 if (!compilationUnit) {
835 qDeleteAll(*resolvedTypeCache);
836 resolvedTypeCache->clear();
837 setError(compiler.compilationErrors());
838 return;
839 }
840
841 const bool trySaveToDisk = writeCacheFile() && !typeRecompilation;
842 if (trySaveToDisk) {
844 if (compilationUnit->saveToDisk(url(), &errorString)) {
846 if (!compilationUnit->loadFromDisk(url(), m_backupSourceCode.sourceTimeStamp(), &error)) {
847 // ignore error, keep using the in-memory compilation unit.
848 }
849 } else {
850 qCDebug(DBG_DISK_CACHE) << "Error saving cached version of"
851 << compilationUnit->fileName() << "to disk:" << errorString;
852 }
853 }
854
855 m_compiledData = std::move(compilationUnit);
856 m_compiledData->typeNameCache = typeNameCache;
857 m_compiledData->resolvedTypes = *resolvedTypeCache;
858 m_compiledData->propertyCaches = std::move(*compiler.propertyCaches());
859 Q_ASSERT(m_compiledData->propertyCaches.count()
860 == static_cast<int>(m_compiledData->objectCount()));
861}
862
863void QQmlTypeData::resolveTypes()
864{
865 // Load the implicit import since it may have additional scripts.
866 if (!m_implicitImportLoaded && !loadImplicitImport())
867 return;
868
869 // Add any imported scripts to our resolved set
870 const auto resolvedScripts = m_importCache->resolvedScripts();
871 for (const QQmlImports::ScriptReference &script : resolvedScripts) {
872 QQmlRefPointer<QQmlScriptBlob> blob = typeLoader()->getScript(script.location);
873 addDependency(blob.data());
874
875 ScriptReference ref;
876 //ref.location = ...
877 if (!script.qualifier.isEmpty())
878 {
879 ref.qualifier = script.qualifier + QLatin1Char('.') + script.nameSpace;
880 // Add a reference to the enclosing namespace
881 m_namespaces.insert(script.qualifier);
882 } else {
883 ref.qualifier = script.nameSpace;
884 }
885
886 ref.script = blob;
887 m_scripts << ref;
888 }
889
890 // Lets handle resolved composite singleton types
891 const auto resolvedCompositeSingletons = m_importCache->resolvedCompositeSingletons();
892 for (const QQmlImports::CompositeSingletonReference &csRef : resolvedCompositeSingletons) {
893 TypeReference ref;
895 if (!csRef.prefix.isEmpty()) {
896 typeName = csRef.prefix + QLatin1Char('.') + csRef.typeName;
897 // Add a reference to the enclosing namespace
898 m_namespaces.insert(csRef.prefix);
899 } else {
900 typeName = csRef.typeName;
901 }
902
903 QTypeRevision version = csRef.version;
904 if (!resolveType(typeName, version, ref, -1, -1, true, QQmlType::CompositeSingletonType))
905 return;
906
907 if (ref.type.isCompositeSingleton()) {
908 ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
909 if (ref.typeData->isWaiting() || m_waitingOnMe.contains(ref.typeData.data())) {
910 qCDebug(lcCycle) << "Possible cyclic dependency detected between"
911 << ref.typeData->urlString() << "and" << urlString();
912 continue;
913 }
914 addDependency(ref.typeData.data());
915 ref.prefix = csRef.prefix;
916
917 m_compositeSingletons << ref;
918 }
919 }
920
921 for (QV4::CompiledData::TypeReferenceMap::ConstIterator unresolvedRef = m_typeReferences.constBegin(), end = m_typeReferences.constEnd();
922 unresolvedRef != end; ++unresolvedRef) {
923
924 TypeReference ref; // resolved reference
925
926 const bool reportErrors = unresolvedRef->errorWhenNotFound;
927
928 QTypeRevision version;
929
930 const QString name = stringAt(unresolvedRef.key());
931
932 bool *selfReferenceDetection = unresolvedRef->needsCreation ? nullptr : &ref.selfReference;
933
934 if (!resolveType(name, version, ref, unresolvedRef->location.line(),
935 unresolvedRef->location.column(), reportErrors,
936 QQmlType::AnyRegistrationType, selfReferenceDetection) && reportErrors)
937 return;
938
939 if (ref.type.isComposite() && !ref.selfReference) {
940 ref.typeData = typeLoader()->getType(ref.type.sourceUrl());
941 addDependency(ref.typeData.data());
942 }
943 if (ref.type.isInlineComponentType()) {
944 QUrl containingTypeUrl = ref.type.sourceUrl();
945 containingTypeUrl.setFragment(QString());
946 if (!containingTypeUrl.isEmpty()) {
947 auto typeData = typeLoader()->getType(containingTypeUrl);
948 if (typeData.data() != this) {
949 ref.typeData = typeData;
950 addDependency(typeData.data());
951 }
952 }
953 }
954
955 ref.version = version;
956 ref.location = unresolvedRef->location;
957 ref.needsCreation = unresolvedRef->needsCreation;
958 m_resolvedTypes.insert(unresolvedRef.key(), ref);
959 }
960
961 // ### this allows enums to work without explicit import or instantiation of the type
962 if (!m_implicitImportLoaded)
963 loadImplicitImport();
964}
965
966QQmlError QQmlTypeData::buildTypeResolutionCaches(
967 QQmlRefPointer<QQmlTypeNameCache> *typeNameCache,
968 QV4::CompiledData::ResolvedTypeReferenceMap *resolvedTypeCache) const
969{
970 typeNameCache->adopt(new QQmlTypeNameCache(m_importCache));
971
972 for (const QString &ns: m_namespaces)
973 (*typeNameCache)->add(ns);
974
975 // Add any Composite Singletons that were used to the import cache
976 for (const QQmlTypeData::TypeReference &singleton: m_compositeSingletons)
977 (*typeNameCache)->add(singleton.type.qmlTypeName(), singleton.type.sourceUrl(), singleton.prefix);
978
979 m_importCache->populateCache(typeNameCache->data());
980
981 for (auto resolvedType = m_resolvedTypes.constBegin(), end = m_resolvedTypes.constEnd(); resolvedType != end; ++resolvedType) {
982 auto ref = std::make_unique<QV4::ResolvedTypeReference>();
983 QQmlType qmlType = resolvedType->type;
984 if (resolvedType->typeData) {
985 if (resolvedType->needsCreation && qmlType.isCompositeSingleton()) {
986 return qQmlCompileError(resolvedType->location, tr("Composite Singleton Type %1 is not creatable.").arg(qmlType.qmlTypeName()));
987 }
988 ref->setCompilationUnit(resolvedType->typeData->compilationUnit());
989 if (resolvedType->type.isInlineComponentType()) {
990 // Inline component which is part of an already resolved type
991 QString icName = qmlType.elementName();
992 Q_ASSERT(!icName.isEmpty());
993
994 const auto compilationUnit = resolvedType->typeData->compilationUnit();
995 ref->setTypePropertyCache(compilationUnit->propertyCaches.at(
997 ref->setType(std::move(qmlType));
998 Q_ASSERT(ref->type().isInlineComponentType());
999 }
1000 } else if (resolvedType->type.isInlineComponentType()) {
1001 ref->setType(qmlType);
1002
1003 // Inline component
1004 // If it's defined in the same file we're currently compiling, we don't want to use it.
1005 // We're going to fill in the property caches later after all.
1006 if (qmlType.isValid()
1008
1009 // this is required for inline components in singletons
1010 const QMetaType type = qmlType.typeId();
1011 if (auto unit = QQmlMetaType::obtainCompilationUnit(type)) {
1012 ref->setCompilationUnit(std::move(unit));
1013 ref->setTypePropertyCache(QQmlMetaType::propertyCacheForType(type));
1014 }
1015 }
1016 } else if (qmlType.isValid() && !resolvedType->selfReference) {
1017 ref->setType(qmlType);
1018 Q_ASSERT(ref->type().isValid());
1019
1020 if (resolvedType->needsCreation && !qmlType.isCreatable()) {
1021 QString reason = qmlType.noCreationReason();
1022 if (reason.isEmpty())
1023 reason = tr("Element is not creatable.");
1024 return qQmlCompileError(resolvedType->location, reason);
1025 }
1026
1028 // It can only have (revisioned) properties or methods if it has a metaobject
1030 ref->setTypePropertyCache(
1032 }
1033 }
1034 ref->setVersion(resolvedType->version);
1035 ref->doDynamicTypeCheck();
1036 resolvedTypeCache->insert(resolvedType.key(), ref.release());
1037 }
1038 QQmlError noError;
1039 return noError;
1040}
1041
1042bool QQmlTypeData::resolveType(const QString &typeName, QTypeRevision &version,
1043 TypeReference &ref, int lineNumber, int columnNumber,
1044 bool reportErrors, QQmlType::RegistrationType registrationType,
1045 bool *typeRecursionDetected)
1046{
1047 QQmlImportNamespace *typeNamespace = nullptr;
1048 QList<QQmlError> errors;
1049
1050 bool typeFound = m_importCache->resolveType(
1051 typeLoader(), typeName, &ref.type, &version, &typeNamespace, &errors, registrationType,
1052 typeRecursionDetected);
1053 if (!typeNamespace && !typeFound && !m_implicitImportLoaded) {
1054 // Lazy loading of implicit import
1055 if (loadImplicitImport()) {
1056 // Try again to find the type
1057 errors.clear();
1058 typeFound = m_importCache->resolveType(
1059 typeLoader(), typeName, &ref.type, &version, &typeNamespace, &errors,
1060 registrationType, typeRecursionDetected);
1061 } else {
1062 return false; //loadImplicitImport() hit an error, and called setError already
1063 }
1064 }
1065
1066 if ((!typeFound || typeNamespace) && reportErrors) {
1067 // Known to not be a type:
1068 // - known to be a namespace (Namespace {})
1069 // - type with unknown namespace (UnknownNamespace.SomeType {})
1071 if (typeNamespace) {
1072 error.setDescription(QQmlTypeLoader::tr("Namespace %1 cannot be used as a type").arg(typeName));
1073 } else {
1074 if (errors.size()) {
1076 } else {
1077 // this should not be possible!
1078 // Description should come from error provided by addImport() function.
1079 error.setDescription(QQmlTypeLoader::tr("Unreported error adding script import to import database"));
1080 }
1081 error.setUrl(m_importCache->baseUrl());
1082 error.setDescription(QQmlTypeLoader::tr("%1 %2").arg(typeName).arg(error.description()));
1083 }
1084
1085 if (lineNumber != -1)
1086 error.setLine(lineNumber);
1087 if (columnNumber != -1)
1088 error.setColumn(columnNumber);
1089
1092 return false;
1093 }
1094
1095 return true;
1096}
1097
1099 const QQmlRefPointer<QQmlScriptBlob> &blob, const QV4::CompiledData::Location &location,
1100 const QString &nameSpace, const QString &qualifier)
1101{
1103 ref.script = blob;
1104 ref.location = location;
1105 ref.qualifier = qualifier.isEmpty() ? nameSpace : qualifier + QLatin1Char('.') + nameSpace;
1106
1107 m_scripts << ref;
1108}
1109
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
const_iterator ConstIterator
Qt-style synonym for QHash::const_iterator.
Definition qhash.h:1289
void clear() noexcept(std::is_nothrow_destructible< Node >::value)
Removes all items from the hash and frees up all memory used by it.
Definition qhash.h:951
QV4::ExecutionEngine * handle() const
Definition qjsengine.h:298
qsizetype size() const noexcept
Definition qlist.h:397
bool isEmpty() const noexcept
Definition qlist.h:401
T & first()
Definition qlist.h:645
value_type takeFirst()
Definition qlist.h:566
void prepend(rvalue_ref t)
Definition qlist.h:473
void reserve(qsizetype size)
Definition qlist.h:753
void clear()
Definition qlist.h:434
\inmodule QtCore
Definition qmetatype.h:341
constexpr const char * name() const
Definition qmetatype.h:2680
QDateTime sourceTimeStamp() const
QString readAll(QString *error) const
bool isError() const
Returns true if the status is Error.
bool isCompleteOrError() const
Returns true if the status is Complete or Error.
void addDependency(QQmlDataBlob *)
Wait for blob to become complete or to error.
QList< QQmlError > errors() const
Return the errors on this blob.
QUrl url() const
Returns the physical url of the data.
QQmlTypeLoader * typeLoader() const
QUrl finalUrl() const
Returns the logical URL to be used for resolving further URLs referred to in the code.
QList< QQmlDataBlob * > m_waitingOnMe
virtual void allDependenciesDone()
Called when all blobs waited for have completed.
QString finalUrlString() const
Returns the finalUrl() as a string.
Type type() const
Returns the type provided to the constructor.
void setError(const QQmlError &)
Mark this blob as having errors.
QString urlString() const
static QQmlEnginePrivate * get(QQmlEngine *e)
The QQmlEngine class provides an environment for instantiating QML components.
Definition qqmlengine.h:57
The QQmlError class encapsulates a QML error.
Definition qqmlerror.h:18
void setColumn(int)
Sets the error column number.
void setLine(int)
Sets the error line number.
void setDescription(const QString &)
Sets the error description.
void setUrl(const QUrl &)
Sets the url for the file that caused this error.
void populateCache(QQmlTypeNameCache *cache) const
QList< CompositeSingletonReference > resolvedCompositeSingletons() const
QList< ScriptReference > resolvedScripts() const
bool addInlineComponentImport(QQmlImportInstance *const importInstance, const QString &name, const QUrl importUrl)
void setBaseUrl(const QUrl &url, const QString &urlString=QString())
Sets the base URL to be used for all relative file imports added.
QUrl baseUrl() const
QTypeRevision addImplicitImport(QQmlTypeLoader *typeLoader, QString *localQmldir, QList< QQmlError > *errors)
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
static bool isLocal(const QString &url)
static QQmlType findCompositeType(const QUrl &url, const QQmlRefPointer< QV4::CompiledData::CompilationUnit > &compilationUnit, CompositeTypeLookupMode mode=NonSingleton)
static bool equalBaseUrls(const QUrl &aUrl, const QUrl &bUrl)
static QQmlType findInlineComponentType(const QUrl &url, const QQmlRefPointer< QV4::CompiledData::CompilationUnit > &compilationUnit)
static QList< QQmlDirParser::Import > moduleImports(const QString &uri, QTypeRevision version)
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...
static QQmlRefPointer< QV4::CompiledData::CompilationUnit > obtainCompilationUnit(QMetaType type)
static QQmlPropertyCache::ConstPtr propertyCacheForType(QMetaType metaType)
QQmlPropertyCache::ConstPtr at(int index) const
static QQmlPropertyIndex fromEncoded(qint32 encodedIndex)
QVector< QQmlError > validate()
T * data() const
void reset(T *t=nullptr)
bool isNull() const
QQmlRefPointer< QQmlScriptData > scriptData() const
QV4::CompiledData::CompilationUnit * compilationUnit() const
void done() override
Invoked once data has either been received or a network error occurred, and all dependencies are comp...
void registerCallback(TypeDataCallback *)
void completed() override
Invoked on the main thread sometime after done() was called on the load thread.
void downloadProgressChanged(qreal) override
Called when the download progress of this blob changes.
void unregisterCallback(TypeDataCallback *)
void initializeFromCachedUnit(const QQmlPrivate::CachedQmlUnit *unit) override
QQmlType qmlType(const QString &inlineComponentName=QString()) const
void dataReceived(const SourceCodeData &) override
Invoked when data for the blob is received.
void scriptImported(const QQmlRefPointer< QQmlScriptBlob > &blob, const QV4::CompiledData::Location &location, const QString &nameSpace, const QString &qualifier) override
QString stringAt(int index) const override
QByteArray typeClassName() const
~QQmlTypeData() override
void allDependenciesDone() override
Called when all blobs waited for have completed.
std::shared_ptr< PendingImport > PendingImportPtr
Blob(const QUrl &url, QQmlDataBlob::Type type, QQmlTypeLoader *loader)
bool addImport(const QV4::CompiledData::Import *import, QQmlImports::ImportFlags, QList< QQmlError > *errors)
bool fetchQmldir(const QUrl &url, PendingImportPtr import, int priority, QList< QQmlError > *errors)
const QQmlImports * imports() const
QQmlMetaType::CachedUnitLookupError m_cachedUnitStatus
QVector< PendingImportPtr > m_unresolvedImports
bool loadDependentImports(const QList< QQmlDirParser::Import > &imports, const QString &qualifier, QTypeRevision version, quint16 precedence, QQmlImports::ImportFlags flags, QList< QQmlError > *errors)
QQmlRefPointer< QQmlImports > m_importCache
The QQmlTypeLoader class abstracts loading files and their dependencies over the network.
QQmlEngine * engine() const
Return the QQmlEngine associated with this loader.
QQmlRefPointer< QQmlTypeData > getType(const QUrl &unNormalizedUrl, Mode mode=PreferSynchronous)
Returns a QQmlTypeData for the specified url.
QQmlRefPointer< QQmlScriptBlob > getScript(const QUrl &unNormalizedUrl)
Return a QQmlScriptBlob for url.
const QQmlTypeLoaderQmldirContent qmldirContent(const QString &filePath)
Return a QQmlTypeLoaderQmldirContent for absoluteFilePath.
void add(const QHashedString &name, int sciptIndex=-1, const QHashedString &nameSpace=QHashedString())
bool isCreatable() const
Definition qqmltype.cpp:584
bool isCompositeSingleton() const
Definition qqmltype.cpp:639
@ AnyRegistrationType
Definition qqmltype_p.h:167
@ CompositeSingletonType
Definition qqmltype_p.h:164
QTypeRevision version() const
Definition qqmltype.cpp:112
QString noCreationReason() const
Definition qqmltype.cpp:577
QMetaType typeId() const
Definition qqmltype.cpp:668
QString qmlTypeName() const
Definition qqmltype.cpp:469
QUrl sourceUrl() const
Definition qqmltype.cpp:767
const QMetaObject * metaObject() const
Definition qqmltype.cpp:683
bool isValid() const
Definition qqmltype_p.h:54
QString elementName() const
Definition qqmltype.cpp:462
bool containsRevisionedAttributes() const
Definition qqmltype.cpp:699
T * data() const noexcept
Returns the value of the pointer referenced by this object.
bool isNull() const noexcept
Returns true if this object refers to \nullptr.
void reset(T *other=nullptr) noexcept(noexcept(Cleanup::cleanup(std::declval< T * >())))
Deletes the existing object it is pointing to (if any), and sets its pointer to other.
iterator insert(const T &value)
Definition qset.h:155
\inmodule QtCore
Definition qstringview.h:78
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:129
QString left(qsizetype n) const &
Definition qstring.h:363
qsizetype lastIndexOf(QChar c, Qt::CaseSensitivity cs=Qt::CaseSensitive) const noexcept
Definition qstring.h:296
QString mid(qsizetype position, qsizetype n=-1) const &
Definition qstring.cpp:5300
bool isEmpty() const noexcept
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:192
\inmodule QtCore
\inmodule QtCore
Definition qurl.h:94
QUrl resolved(const QUrl &relative) const
Returns the result of the merge of this URL with relative.
Definition qurl.cpp:2725
void setFragment(const QString &fragment, ParsingMode mode=TolerantMode)
Sets the fragment of the URL to fragment.
Definition qurl.cpp:2648
QString scheme() const
Returns the scheme of the URL.
Definition qurl.cpp:1991
void setReferencesCompilationUnit(bool doReference)
QHash< int, QWidget * > hash
[35multi]
qDeleteAll(list.begin(), list.end())
QSet< QString >::iterator it
auto mo
[7]
Combined button and popup list for selecting options.
std::function< QByteArray()> DependentTypesHasher
Q_MULTIMEDIA_EXPORT QString errorString(HRESULT hr)
DBusConnection const char DBusError * error
typedef QByteArray(EGLAPIENTRYP PFNQGSGETDISPLAYSPROC)()
@ QtWarningMsg
Definition qlogging.h:31
#define Q_LOGGING_CATEGORY(name,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
const char * typeName
GLint location
GLuint index
[2]
GLuint GLuint end
GLenum GLenum GLsizei count
GLuint object
[3]
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLenum type
GLuint GLsizei const GLchar * message
GLint ref
GLuint name
GLsizei GLsizei GLchar * source
GLhandleARB obj
[2]
GLuint64EXT * result
[6]
GLfloat GLfloat p
[1]
static void add(QPainterPath &path, const QWingedEdge &list, int edge, QPathEdge::Traversal traversal)
static qreal component(const QPointF &point, unsigned int i)
QQmlEngine * qmlEngine(const QObject *obj)
Definition qqml.cpp:80
QT_BEGIN_NAMESPACE QQmlError qQmlCompileError(const QV4::CompiledData::Location &location, const QString &description)
int objectForId(const ObjectContainer *objectContainer, const CompiledObject &component, int id)
static bool addTypeReferenceChecksumsToHash(const QList< QQmlTypeData::TypeReference > &typeRefs, QHash< quintptr, QByteArray > *checksums, QCryptographicHash *hash)
static const char * qmlTypeName(const QObject *object)
#define Q_ASSERT(cond)
Definition qrandom.cpp:47
QtPrivate::QRegularExpressionMatchIteratorRangeBasedForIterator begin(const QRegularExpressionMatchIterator &iterator)
QScopeGuard< typename std::decay< F >::type > qScopeGuard(F &&f)
[qScopeGuard]
Definition qscopeguard.h:60
SSL_CTX int void * arg
QLatin1StringView QLatin1String
Definition qstringfwd.h:31
#define tr(X)
#define Q_UNUSED(x)
unsigned int quint32
Definition qtypes.h:50
double qreal
Definition qtypes.h:187
QUrl baseUrl
QObject::connect nullptr
QNetworkAccessManager manager
QJSEngine engine
[0]
\inmodule QtCore \reentrant
Definition qchar.h:18
bool contains(const AT &t) const noexcept
Definition qlist.h:45
\inmodule QtCore
void resolveMissingPropertyCaches(QQmlPropertyCacheVector *propertyCaches) const
const AOTCompiledFunction * aotCompiledFunctions
const QV4::CompiledData::Unit * qmlData
static bool canCreateClassNameTypeByUrl(const QUrl &url)
QQmlRefPointer< QQmlScriptBlob > script
QV4::CompiledData::Location location
virtual void typeDataProgress(QQmlTypeData *, qreal)
virtual void typeDataReady(QQmlTypeData *)
QHash< QString, InlineComponentData > inlineComponentData
int inlineComponentId(const QString &inlineComponentName) const
Q_QML_EXPORT bool saveToDisk(const QUrl &unitUrl, QString *errorString)
ResolvedTypeReference * resolvedType(int id) const
QVector< QQmlRefPointer< QQmlScriptData > > dependentScripts
ResolvedTypeReferenceMap resolvedTypes
bool verifyChecksum(const CompiledData::DependentTypesHasher &dependencyHasher) const
QQmlRefPointer< QQmlTypeNameCache > typeNameCache
void finalizeCompositeType(const QQmlType &type)
const CompiledObject * objectAt(int index) const
Q_QML_EXPORT bool loadFromDisk(const QUrl &url, const QDateTime &sourceTimeStamp, QString *errorString)
void collectFromObject(const CompiledObject *obj)
void collectFromObjects(Iterator it, Iterator end)
StringTableGenerator stringTable
QString stringForIndex(int index) const
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
bool isSingleton() const