aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlmetatype.cpp
Commit message (Collapse)AuthorAgeFilesLines
* QtQml: Straighten out some logging categoriesUlf Hermann47 hours1-2/+2
| | | | | | | | | | | Either make them static or declare them in a header. We want them to be static wherever possible, in order to reduce the number of visible symbols. If they can't be static, however, they should at least be declared in only one place. Task-number: QTBUG-67692 Change-Id: I91fa641b46510ea8902b478d31dfd60d34b5f580 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Use QHash/QMap's constFind() to avoid unnecessary detachesVladimir Belyavsky2024-04-221-4/+4
| | | | | | | | Use QHash/QMap's constFind() instead of non-const find() where applicable to avoid unnecessary detaches. Change-Id: I6b31af1d163d11deb229681ff7e2f6c9f8335d8c Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QtQml: Consider value types when looking for metaobjectsUlf Hermann2024-02-151-4/+15
| | | | | | | | | | | We have quite a few types with only extension metaobjects now. Move the functionality to retrieve the metaobject into QQmlType where it belongs. Pick-to: 6.7 6.6 Fixes: QTBUG-119829 Change-Id: I2b99b1a305d8726547ae0512d3c832799a4e4b04 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io>
* QtQml: Do not speculatively create ICs for non-composite typesUlf Hermann2024-02-081-2/+1
| | | | | | | | | This just clobbers the type registry with useless trash. Pick-to: 6.7 6.6 Task-number: QTBUG-120506 Change-Id: I9c56930493cfbe343359f6cb22eac2a6c76d01a2 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Move header verification into CompiledData::UnitUlf Hermann2024-01-231-1/+1
| | | | | | | | There is nothing that makes it depend on ExecutableCompilationUnit. Change-Id: I482dfc0177530f748bb90e5373c64ca5558d8629 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Use CompiledData::CompilationUnit in more placesUlf Hermann2024-01-201-12/+30
| | | | | | | | | | We rarely actually need the executable CU, and where we need it, we can dynamically create or retrieve it from the engine. To that end, store all the CUs in the same container in the engine. Change-Id: I0b786048c578ac4f41ae4aee601da850fa400f2e Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Move qmlType into base CUUlf Hermann2024-01-181-3/+3
| | | | | Change-Id: I81ae9a4d24518dffc5b924994d45203958bb9546 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Assign unique placeholder names to anonymous metatypesUlf Hermann2024-01-171-0/+1
| | | | | | | | | They cannot all be called "*". This becomes an issue when we start to properly remove the unnecessary metatypes. Pick-to: 6.7 Change-Id: I189c0b8b32b5039884f2570df845fedbc62f6e94 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Don't create metatypes for procedurally registered compositesUlf Hermann2024-01-171-9/+14
| | | | | | | | | | | | | | We never want to find or insert them in the compositeTypes. Anytime an engine wants to use such a type it has to compile it all the way. Amends commit b48bb41681f561b59a4ce9c9d0ac95b23d5ccb1e. Pick-to: 6.7 Fixes: QTBUG-121014 Change-Id: I027f977643db01dac25d8fbc06a6d3e75a7183f5 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Nicolas Fella <nicolas.fella@kdab.com>
* QtQml: Move inlineComponentData and icRootName into base CUUlf Hermann2024-01-131-3/+3
| | | | | | Change-Id: I89e44644b083681f069d1d7a385bec68b4bfd80b Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Clear stale compilation units more thoroughlyUlf Hermann2024-01-111-16/+37
| | | | | | | | | There are various places where we can still hold references. Clean them up when asked to do so. Also, free unused types and caches outside the type loader mutex, and only once on engine shutdown. Change-Id: Iae77cd6f50ad847d29a7eae4ac5c7c1c2524065d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Don't unnecessarily detour through the CU to look up typesUlf Hermann2023-10-191-2/+7
| | | | | | | | | | | Since we also store partial types as QQmlType now, we can just look them up the regular way. Pick-to: 6.6 6.5 6.2 Fixes: QTBUG-117788 Change-Id: Id3e81853f802419f1121ef5e856c3272a3c977a1 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QtQml: Store singleton typename as UTF-8 QByteArrayUlf Hermann2023-08-301-1/+1
| | | | | | | | We rarely want to read it as QString, and we almost always set it from UTF-8 data. Change-Id: I389e9a6de140d8adc09ccc3350685b2d47e03eb8 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Key singletons by singleton instance infoUlf Hermann2023-08-301-21/+26
| | | | | | | | | | | | | | | | | | | | We can keep the singleton instance info the same across multiple types created in a single registration call. The result is that we only get one singleton instance per engine, rather than separate ones for each version. If you invoke qmlRegisterSingletonType separately, you still get separate instances, though. [ChangeLog][QtQml][Important Behavior Changes] The QML engine will now refrain from creating separate instances of a singleton type for each version it is registered for if the singleton is registered declaratively (using QML_SINGLETON). The behavior of procedurally registered singletons (using the qmlRegisterSingletonType() family of functions) remains the same: For each registration call, a separate singleton instance is created. Task-number: QTBUG-116432 Change-Id: Ic8a5de0f88ef530670cfd81b192201a8ab49b2f7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Remove unused instanceMetaObject memberUlf Hermann2023-08-281-2/+0
| | | | | Change-Id: Ic48c065fdd5392b410ae9eee7a6c1e3471564920 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Slightly optimize QQmlType proxy creation methodsUlf Hermann2023-07-111-10/+17
| | | | | | | | | We don't need the metatype data pointer if we're not going to resolve any types. Also, add a comment regarding the questionable nature of the extension resolution algorithm. Change-Id: I90ba161caea51c5915b140d1029b2327fba80a3b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Clean up lazy-loading of parts of QQmlTypePrivateUlf Hermann2023-07-111-6/+0
| | | | | | | | | | | | | | | | | The meta objects and the enums are lazily loaded semi-independently from each other. Their data structures take up a lot of space. We only want to incur that cost if they are actually needed. Furthermore, the lazy-loading needs to be thread-safe. The easiest way to make a thread safe lazy loading structure is via a mutable atomic pointer to an immutable object. Refactor QQmlTypePrivate to do just that. This reduces the memory usage of the base structure by about 50%, cuts down on the locking required to set up the extra aspects, and generally makes the code more readable. Change-Id: I815338d3e4de02b2f535ab2fee748bba47719efc Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QQmlType: Re-organize QQmlTypePrivate to reduce memory usageUlf Hermann2023-07-061-42/+42
| | | | | | | | | | | | The iid is only used for interfaces, and re-ordering the members saves some padding. Also, avoid extra indirection where possible. QUrl is only one pointer to begin with, just like QMetaSequence. We can store them directly in the union. Finally, rename the extraData members so that we can easily recognize them. Change-Id: Ia9c524ea65f8137b264a7dfd9459369c90ce1670 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Use QQmlType as container for composite types (inline or not)Ulf Hermann2023-06-221-159/+246
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This gives us a unified interface to all kinds of QML types at run time and reduces the effort of finding corresponding type attributes. QQmlType is much larger than CompositeMetaTypeIds. Most composite types, however, are initially referenced by URL, and we call typeForUrl anyway. typeForUrl already creates a mostly functional QQmlType; we only need to add the dynamic metatypes. The same type can be retrieved later and associated with the actual CU using the compositeTypes hash. That way, we don't need any extra type. We do, however, incur the cost of creating the QMetaTypePrivate instances when first referencing a type. This could be optimized, like many things in this area, by using thread safe lazy initialization. Now some QQmlTypes implicitly depend on the CUs they were created for. This creates problems if the CUs are removed but the types still persist. Such a situation can arise if you create and delete engines. In order to avoid it, we: 1. Make the compositeTypes hold a strong reference to the CUs 2. When unlinking, avoid dropping the property caches (as those are used to hold the metaobjects) Now, however we got a cyclic reference between the CU and its QQmlType(s). To resolve this, we clear the QQmlTypes on unlinking. Finally, to avoid deletion recursion when clearing the last CUs on destruction of the QQmlMetaTypeData, we move the compilation units out of the way first. All of this still doesn't work if multiple CUs hold the same QQmlType, since compositeTypes can only hold one CU per type and that may be the one that gets removed first. Therefore, we cannot allow such a situation to happen and have to create a new QQmlType if it arises. It can only arise if you have multiple engines loading the same QML components, which should be fairly rare. For inline components, we apply a similar trick: You can either find an inline component by Url, and receive any type that matches, no matter what CU it belongs to. Or you can request an inline component type that belongs to a specific CU. It turns out we don't have to store the containing type of an IC at all. Also, we slightly change the naming of internal components' "class names" since we want to use the inline components' element names for them. Change-Id: I0ef89bd4b0a02cc927aed2525e72f6bff56df626 Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
* QtQml: Move inline component registry to QQmlMetaTypeDataUlf Hermann2023-05-301-4/+45
| | | | | | | | | | | | QQmlTypePrivate is supposed to be immutable. "Amending" an existing QQmlTypePrivate with inline components after the fact is risky. It's hard to guarantee that no other thread accesses the data in between. Also, this way we need one lookup table for all the inline components rather than a separate (mostly empty) one for each type. Change-Id: I7a06c0faca1f8244dd2bdc7aa775abd8e2f92125 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Index inline components by name rather than IDUlf Hermann2023-05-301-1/+1
| | | | | | | | | | | The ID can only be determined once the compilation unit is present. It depends on the order of objects in the compiled data. The name is always available. Indexing by name increases the overhead. However, since we don't have to "amend" the ID later on and since we only need one lookup table rather than two per type now, it's probably worth it. Change-Id: I478de505a1934b5b6ab340b4be4fa5da4e95aeb3 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Undeprecate AOTCompiledFunctionUlf Hermann2023-05-231-1/+1
| | | | | | | We're going to call the JavaScript-typed functions a different name. Change-Id: If92c3fb1b16b1b0bd7d009e7dd712ae6405e1232 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Register all builtinsUlf Hermann2023-05-221-5/+19
| | | | | | | | | | | | We need run time access to the QQmlType instances of all the builtins in order to properly coerce types without special casing everything all the time. Since we can now have QML types without metaobjects, we need to check for the metaobject in a few places where we didn't need to check before. Change-Id: Ib22cbb12c60ebdce4897c3f3338851e8b925926f Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Remove some references to Q_ENUMSFabian Kosmale2023-05-221-1/+1
| | | | | | | | | | Q_ENUM is the preferred way to expose enums to the metatype system since quite a few years. Tast-number: QTBUG-113229 Pick-to: 6.5 6.2 Change-Id: Ie778d0d4620e73742ca59bb37112e939489ffa4d Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlMetaType: Clear property caches on qmlClearTypeRegistrationsUlf Hermann2023-02-141-0/+1
| | | | | | | | | | | | Otherwise we may retain dangling pointers referencing invalid property caches. Some metaobjects are created on the heap. If the memory manager decides to re-use the heap space for new metaobjects, we can retrieve the invalid property caches. Pick-to: 6.5 6.4 6.2 Task-number: QTBUG-110933 Change-Id: Ic00bb852151bcf58ba6ae798a6bf2cea686a9e10 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Fix some qsizetype vs. quint32 problemsUlf Hermann2023-01-061-1/+1
| | | | | | | | | | On 32bit platforms you cannot losslessly convert quint32 to qsizetype. However, in the places we are facing here, we are only interested in signed 32bit numbers anyway. Pick-to: 6.5 6.2 Change-Id: I93a07c2847bd5bfae426dccbb6c0e33c5758442d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Allow more fine grained control of the disk cacheUlf Hermann2023-01-021-1/+26
| | | | | | | | | You can now enable and disable the AOT-compiled code and the loading and saving of .qmlc files separately. Fixes: QTBUG-101358 Change-Id: I1305c4f2f75d8cff544a127e956589d1ed1aeb52 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Fix precedence between importsUlf Hermann2022-11-081-3/+10
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | So far we have "normal", "low precedence", and "implicit" imports. Normal imports were ordered in document order, later imports overriding earlier ones. Low precedence imports were ordered in intractable confusion, and implicit imports were added last, with the actual implicit import first, and any dependencies of it after it in intractable confusion. Since that gives us problems when QtQml is split into an empty "meta" module and a number of dependencies, we have to clear out the confusion. Following the principle that direct imports have higher precedence than indirect ones, we can give each import a precedence number, depending on whether it is implicitly imported or not, and how much the importer has recursed to reach it. Ordering the imports by that number results in a less confused structure, more accessible to reason. Also, module imports were added in different order depending on whether they were revisioned or not. Add them always in the same order. [ChangeLog][QtQml][Important Behavior Changes] The precedence of imports that expose different types for the same name has changed. Previously the algorithm was rather confused. Now, the rule of thumb is that more direct imports override more indirect ones. That means QtObject imported directly from QtQml is of higher precedence than QtObject imported from QtQml via QtQuick. Where that still leaves ambiguities, imports later in the document override imports earlier in the document. Any explicit imports and their dependencies always override the implicit import and its dependencies. Task-number: QTBUG-105240 Change-Id: I5f95f6bb8367087b9d977cb01f434d01bb402a3e Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Port from container::count() and length() to size() - V5Marc Mutz2022-10-131-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8, but extended to handle typedefs and accesses through pointers, too: const std::string o = "object"; auto hasTypeIgnoringPointer = [](auto type) { return anyOf(hasType(type), hasType(pointsTo(type))); }; auto derivedFromAnyOfClasses = [&](ArrayRef<StringRef> classes) { auto exprOfDeclaredType = [&](auto decl) { return expr(hasTypeIgnoringPointer(hasUnqualifiedDesugaredType(recordType(hasDeclaration(decl))))).bind(o); }; return exprOfDeclaredType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes)))); }; auto renameMethod = [&] (ArrayRef<StringRef> classes, StringRef from, StringRef to) { return makeRule(cxxMemberCallExpr(on(derivedFromAnyOfClasses(classes)), callee(cxxMethodDecl(hasName(from), parameterCountIs(0)))), changeTo(cat(access(o, cat(to)), "()")), cat("use '", to, "' instead of '", from, "'")); }; renameMethod(<classes>, "count", "size"); renameMethod(<classes>, "length", "size"); except that on() was replaced with a matcher that doesn't ignoreParens(). a.k.a qt-port-to-std-compatible-api V5 with config Scope: 'Container'. Change-Id: I58e1b41b91c34d2e860dbb5847b3752edbfc6fc9 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Port from qAsConst() to std::as_const()Marc Mutz2022-10-071-4/+4
| | | | | | | | | | | | | | We've been requiring C++17 since Qt 6.0, and our qAsConst use finally starts to bother us (QTBUG-99313), so time to port away from it now. Since qAsConst has exactly the same semantics as std::as_const (down to rvalue treatment, constexpr'ness and noexcept'ness), there's really nothing more to it than a global search-and-replace. Task-number: QTBUG-99313 Change-Id: I601bf70f020f511019ed28731ba53b14b765dbf0 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Port from container::count() and length() to size()Marc Mutz2022-10-071-3/+3
| | | | | | | | | | | | | | | | | | | | This is a semantic patch using ClangTidyTransformator as in qtbase/df9d882d41b741fef7c5beeddb0abe9d904443d8: auto QtContainerClass = anyOf( expr(hasType(cxxRecordDecl(isSameOrDerivedFrom(hasAnyName(classes))))).bind(o), expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o)); makeRule(cxxMemberCallExpr(on(QtContainerClass), callee(cxxMethodDecl(hasAnyName({"count", "length"), parameterCountIs(0))))), changeTo(cat(access(o, cat("size"), "()"))), cat("use 'size()' instead of 'count()/length()'")) a.k.a qt-port-to-std-compatible-api with config Scope: 'Container', with the extended set of container classes recognized. Change-Id: Idb1f75dfe2323bd1d9e8b4d58d54f1b4b80c7ed7 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmltc: support basic inline componentsSami Shalayel2022-09-261-1/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch adds basic inline component support to qmltc. Implementation details: * added tests: ** (for all tests: see if QQmlComponent would do the same thing) ** try simple inline components ** try inline components extending other inline components ** try recursive inline components (inline component A contain a B that itself contains a A) ** make sure ids in inline components are in their own context, and ** make sure alias inside of inline components work ** remove qmltc_qprocess that tests the error message when inline components are encountered ** test that inline components get their own context (by aliasing a property that they should not be able to see) ** test that also empty components work ** other tests inspired from those at tst_qqmllanguage * separate types depending on the inline component they belong in qmltcvisitor and qmltccompiler ** mostly by replacing T with QHash<QString, T>, where the belonging inline component name serves as hash key ** added a list of inline component names in qmltc * generate correct qmltc-code for inline components ** as they sometimes have mimic a document root and sometimes not ** generate their own "typeCount"-method ** fixed naming used in qmltc generated code by using the inline component names from the qqmljsscope. There is one missing feature (using inline components from other files, using QmlFileName.MyInlineComponent) that will be added in a separate commit. Fixes: QTBUG-106882 Change-Id: Iabe1a8b787027367d73d34bcd93c5f7b5480d217 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Allow more options for creating value types from JS objectsUlf Hermann2022-09-241-17/+6
| | | | | | | | | | | | | | | | | | | | We allow value types to be created 1. by calling Q_INVOKABLE constructors 2. by setting their values from properties of a JS object Both have to be opted into by setting a class info. If opted into, these options override the existing methods. When a a type can be created by setting its properties, that implies you can also initialize it using an invokable constructor. However, when given a JS object, the properties method is used. We keep this internal and undocumented for now. As the last try (the create(QJSValue) methods and QJSValue ctors) was not that stellar, let's first wait a bit and see if we're getting it right this time around. Fixes: QTBUG-106480 Change-Id: I767230924afcba032d501846cc3263dad57b7bf0 Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Qml: use an enum for the registration struct versionsUlf Hermann2022-09-141-2/+4
| | | | | | | This way we can see more easily what we're checking for. Change-Id: I44b16e8b71ec967b736a4fe5fe0fcbdf28692b90 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtQml: Fix internal documentation of QQmlMetaType::qmlType()Ulf Hermann2022-08-041-2/+6
| | | | | Change-Id: I12cdde9f966cce362f1c855cd47288dcba064c55 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QQmlMetaType::registerPluginTypes - fix unused variable warningIvan Solovev2022-07-251-0/+2
| | | | | | | | | | | ... when compiling with QT_DISABLE_DEPRECATED_BEFORE >= 0x060300. This warning is treated as error in some configs, so simply use Q_UNUSED() on the variable. Task-number: QTBUG-104950 Pick-to: 6.4 6.3 Change-Id: Id5d06ea8fb0a89cc28a8519b443f8272b4417aa5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Use SPDX license identifiersLucie Gérard2022-06-111-38/+2
| | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Pick-to: 6.4 Task-number: QTBUG-67283 Change-Id: I63563bbeb6f60f89d2c99660400dca7fab78a294 Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
* Revert "Revise QQmlProxyMetaObject and extension chain creation"Jani Heikkinen2022-05-311-113/+37
| | | | | | | | | This reverts commit ff0b9ec6bf817f741e3c9fefbfcd55592e9b2542. Reason for revert: QTBUG-103881 Change-Id: I7e333ec854e81fb06f1f84b77125edc78bb181e6 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Revise QQmlProxyMetaObject and extension chain creationAndrei Golubev2022-05-241-37/+113
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Clone the full-ish meta object hierarchy when dealing with extensions: that way we guarantee that shadowing works correctly both ways - extension properties can shadow type properties AND type properties can shadow extension properties (the latter happens when extension belongs to a base type). This was impossible before since we would always put extension proxies on top of the meta object chain, regardless of where in the chain extensions are located. Consider: "C -> B + ExtensionB -> A + ExtensionA" is interpreted as (old) ExtensionB -> ExtensionA -> C -> B -> A ^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ cloned meta objects static meta objects (new) C -> ExtensionB -> B -> ExtensionA -> A -> C -> B -> A ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^ cloned meta objects static meta objects One can notice that we now clone _more_ meta objects: this is to be able to to create a chain with correctly ordered properties Unify the proxy data creation under QQmlMetaType::proxyData() Update QQmlProxyMetaObject which now has to deal with different types of proxies: not only extensions but also "cloned" self. CustomCall metaCall() of QQmlProxyMetaObject is also adjusted to ignore non-extensions Change-Id: I40e1547a9c05a8504ab98bc06a6bc412a2460783 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* Support extension property revisionsAndrei Golubev2022-05-241-3/+13
| | | | | | | | | | | | | | | | | | | | Previously the extension's property revision would make the property unusable since extensions would've been skipped from property cache construction w.r.t. revisions This is due to the meta object cloning that we do for extension types (since we put the cloned meta object on top of the meta object hierarchy for the QQmlProxyMetaObject). Once cloned, the meta object has no associated QQmlType anymore and we need one to deal with revisions. Overcome this by registering the cloned meta object in the QQmlMetaTypeData From now on, the cloned extension meta object has an associated QQmlType, which is the *extended* type, NOT the *extension* type Change-Id: I4a6a4380278b80e49e1b9874dd458183667e5cb5 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QML: Correctly detect extended typesAndrei Golubev2022-05-231-1/+1
| | | | | | | | | | | | | | | | | | | Introduce a compile-time procedure to distinguish types without extensions but with base type extensions from types with direct extensions. Previously, we would have treated both cases the same due to the C++ mechanism employed to mark a type as extension-containing As a drive by, make QQmlMetaType::clone() use class name of the extension when we clone the extension [ChangeLog][Important Behavior Changes] A derived type is no longer considered to be extended itself when only its base type is extended. Instead, the extension only exists on the base type. Change-Id: I74092a5f88cad09c1e07626ae90bb986db0da73d Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlProxyMetaObject: Ignore properties/methods of non-creatable proxiesAndrei Golubev2022-05-041-27/+30
| | | | | | | | | | | | | | | | | | | | | | | Qt/QML allows marking a type with QML_EXTENDED_NAMESPACE(Type) where Type is a Q_OBJECT. In this case, we have a Type-specific meta object but do not have an extension function to create the object of that Type with, causing us a subtle runtime crash. The crash in fact happens when we attempt to access a shadowed property through the extension object (which surely fails since there's no extension object) Fix this by excluding properties and methods when cloning the metaobject for the proxy if we know that the proxy cannot be created. This somewhat matches what the documentation says about QML_EXTENDED_NAMESPACE: When we have a Q_OBJECT/Q_GADGET, methods and properties of that are not exposed As a drive by, add the same check to the QQmlMetaType::proxyData(). While untested, this seems logical since the proxy data assumes valid creation function in this case as well Fixes: QTBUG-103081 Change-Id: I63c6e535d4df5169e0279eb2f588593f43a70640 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* QQmlPropertyCache: Guarantee 1:1 relationship to meta objectUlf Hermann2022-04-251-7/+0
| | | | | | | | | | | | | | | | | | The QQmlPropertyCache ctor that just takes a QMetaObject is really dangerous. It misbehaves for anything but plain QObject. Remove it. Also, realize that we never want to update a property cache "recursively". That is, each property cache maps exactly one metaobject. We cannot cover multiple metaobjects with the same property cache. Finally, any property caches constructed dynamically must not be recorded in the type registry. These caches are not comparable to anything else. Introduce a special method to create them. Fixes: QTBUG-102454 Pick-to: 6.2 6.3 Change-Id: I47a1ff0f467e9444ff9f581ffcdf0a8b5730b0b8 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QML: Add more safety to QQmlPropertyCache usagesUlf Hermann2022-03-181-12/+19
| | | | | | | | | | | | | | We can almost always use QQmlPropertyCache::ConstPtr. The property cache creator needs mutable property caches for a while, but it can seal them when done. The designer integration does ugly stuff, but that should be limited to a specific environment. And the QQmlOpenMetaObject is rather wrong (again). This needs to be addresses in a later change. Task-number: QTBUG-73271 Change-Id: I1c31fd5936c745029d25b909c30b8d14a30f25d3 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QQmlMetaType: Don't duplicate notify signals for extended typesUlf Hermann2022-02-241-14/+14
| | | | | | | | | | | | We have to add the methods first, so that the properties can be associated with their proper notification signals once we add them. If we add the properties first, the "missing" notification signals are synthesized. Pick-to: 6.2 6.3 Fixes: QTBUG-101155 Change-Id: I1aacbf33a24f7a98d05dece77c804bd7cba8a041 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* qmlmodels: Move QModelIndex from QtQmlMaximilian Goldstein2022-02-211-14/+0
| | | | | | | | | | | Moves the QModelIndex value types from QtQml to QtQml.Models as they cannot otherwise be properly resolved in tooling. Pick-to: 6.3 6.2 Fixes: QTBUG-100338 Change-Id: I30fc18b388974238ba8353e87ef09f57f8ceabd1 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* QML: Allow named lists of value typesUlf Hermann2022-01-281-16/+29
| | | | | | | | | | | | | | | | | | | | | | | | We register QList<T> as sequential container type for any value type T we get. This way we can always find a type to use for list<t> with t being a value type. The metatypes are shuffled around so that we have an easier time associating a type with its list and vice versa. As QQmlPropertyData's isQList flag denotes both QQmlListProperty<T> and QList<T> now, we need to use QMetaType::IsQmlList more often. Conversely, any name given to extra sequential containers registered via QML_SEQUENTIAL_CONTAINER is explicitly ignored now. As you can do list<foo> for any type foo now, there is not much of a point in having further named container registrations for the same type. It would just make things more complicated. Mind that the name had already been ignored before, just not explicitly. [ChangeLog][QtQml] You can now use lists of value types in QML. For example a property of type list<int> will hold a list of integers. Task-number: QTBUG-82443 Change-Id: I7bee61cee3963dae5d231bf59f70b8012984371d Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Simplify QQmlMetaTypeInterface and QQmlListMetaTypeInterfaceUlf Hermann2022-01-181-2/+2
| | | | | | | | | | | The previous code gave the impression that we actually had a C++ type there. We haven't. The whole metatype is built only on QObject. Admit that and simplify accordingly. Also provide a way to retrieve the correct metaobject. A metatype for a QObject* that doesn't provide a metaObjectFn is unexpected and causes crashes elsewhere. Change-Id: Iccb0b72d325ea77fb0cf83f7acbe2ef9fe0e06b4 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Move propertyCache- and metaObject-related functions into QQmlMetaTypeUlf Hermann2022-01-181-17/+96
| | | | | | | | | | | | That's where the data resides. This allows us to lock the mutex only once for all those methods, and it makes a large number of engine pointers unnecessary. Finally, we can now find the element type of a QQmlListProperty without supplying an engine. Change-Id: If1ae8eafe8762a112d1ca06f9c92ab8a727d1bda Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Move QJSEnginePrivate::cache() to QQmlMetaTypeUlf Hermann2022-01-181-0/+13
| | | | | | | | | It is just in line with the other propertyCache() methods, and should be treated the same way. The comment made no sense anymore. This allows us to drop more engine pointers. Change-Id: I2e9b479b555c7f771b619e4693d59cbfcf244df6 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>