If we detect a property or method as potentially shadowed, we don't have
to abandon all hope. We can still retrieve it as untyped var. Since
there are a number of things we can do with untyped var, this may still
be useful.
In the same sense, we need to treat function calls as untyped when the
function in question can be shadowed. Calling functions with var
arguments and return types leads to some more interesting situations in
the call frame setup, so we fix that, too.
Task-number: QTBUG-112480
Change-Id: I238d1cf04951f390c73e14ed9e299f2aa72b68cb
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
So far we can only deal with methods that don't change the source array
and don't use iterators or functions as parameters. We also omit
concat() for now. However, indexOf(), lastIndexOf(), includes(),
join(), slice() and toString() are possible already now.
Task-number: QTBUG-112722
Change-Id: Id19c74e8ad25af876bc954c040c767823b7e3259
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
We know that 'this' is a QObject* since the metatypes stack frame
mandates it. Whenever you pass 'this' to anything it's loaded from the
special 'This' stack slot which then triggers a DTZ check. A DTZ check
is a noop if we can prove that the type is statically known, though.
In QmlCompiler, if we have a valid register content, then the register
has been set in all code paths that lead to the instruction in question.
Fixes: QTBUG-111439
Change-Id: I81d1cd140eea63f85628c3bef3a8f6db0a12096d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
In the happy case this just retrieves the internal QList from the list
property. In the sad case it produces a deep copy. That's not worse than
what the interpreter does, though.
Fixes: QTBUG-112227
Change-Id: I8b2b0ac74c90b6dcee876e83a64502756733c1c5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
It can actually be null rather than undefined. We need to generate a
separate check for that and output the correct error messages.
Amends commit 05f56d7c78
Change-Id: Ia795e31805181640cd5be19359af51067d3fc8d6
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
A pointer type can hold bool as either nullptr or some value. We don't
need to produce a QVariant for that.
Change-Id: I368c3fa703d08ff396a5b4702ba7d1f2614b1467
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
JavaScript can coerce anything to bool, so should we.
Change-Id: Id560e4c1dc10b5432c0cedf3110ad3377bbc5f59
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This allows us to do the relevant conversions in a more civilized way,
dropping the outputVariantConversion() method. The latter is brittle
because you have to manually add it to each instruction, and it uses
QMetaType::convert() which is actually not guaranteed to give the same
results as a QML type coercion.
Task-number: QTBUG-94807
Change-Id: I4d6d05a60beb3b4dfc3da6f0142de25667510904
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
If the "Addressable" option to ValueTypeBehavior is set, you can use the
"as" operator to cast a previously unknown type into either undefined
or the given type. We can use this in qmlcachegen to generate efficient
code for further operations on the same type.
In the generated C++ it in fact only works for GetLookup because:
a, We generally don't do SetLookup on value types, yet.
b, We generally don't call methods on value types, yet.
c, We cannot store a union of undefined and a sequence type, yet.
However, getting properties of value types is the most important
application of the new casts so this is well worth it.
As a side effect we can also look up things in potentially undefined
results of other operations now. For example list lookups.
Task-number: QTBUG-94807
Change-Id: Ifdf34f1f3f67b7a0a8953b9ed0e947b74638a28c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
The interpreter does this and so should the enum lookup adapter for
generated C++ code.
Pick-to: 6.5 6.4 6.2
Fixes: QTBUG-109816
Change-Id: I576480c3ca808743ddc0ceaf2f0bd8a1de776a41
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This patch extends the logic for the 2-argument Math.min() and
Math.max() functions by reutilizing the same logic to compare two
elements and evaluate all arguments with the current max or min.
Fixes: QTBUG-108741
Change-Id: I993a26a1d44d66226c751272dfc2dc63330d115d
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
This patch adds support for get lookups of QVariantMap properties.
Setting or modifying is not supported and will reject.
Also, QQmlJSRegisterContent::JavaScriptObjectProperty was
renamed to QQmlJSRegisterContent::GenericObjectProperty
Tests were added to TestQmllint::cleanQmlCode() and
tst_QmlCppCodegen::variantMapLookup().
Pick-to: 6.5
Fixes: QTBUG-105545
Change-Id: I653ee4e7de1fb1514e1e563a92cfc28633268a7e
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Every instance of AUTO_RESOURCE_PREFIX has been replaced by either
qt_standard_project_setup(REQUIRES 6.5) or with
qt_policy(SET QTP0001 NEW), mainly in tests.
In addition, I added a warning message for the case where
AUTO_RESOURCE_PREFIX is used.
Pick-to: 6.5
Task-number: QTBUG-96233
Change-Id: I323a15e9d0bb5fe6ba649365314af9fc2ad67bda
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Oliver Eftevaag <oliver.eftevaag@qt.io>
It should result in NaN, not in 0. The typedArray() test exposes that
ExecutionEngine::toVariant() also gets this wrong. Fix that, too.
[ChangeLog][QtQml][Important Behavior Changes] Converting a JavaScript
value to a double or float, for example by inserting it into a typed
array, now assumes JavaScript type coercion semantics. In particular,
converting a value that is not actually a number now results in NaN
where it previously sometimes resulted in 0.
Pick-to: 6.5 6.4 6.2
Fixes: QTBUG-111179
Change-Id: If24444ae9014c8972761c565a6920f06699e485c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Since we're already using 3 of the 4 enums in PlatformDialogHelper, we
can just as well declare PlatformDialogHelper as extended namespace and
avoid all the fiddling with Q_ENUMS and QFLAGS.
As an additional upside, we get code using those enums to compile to
C++ this way.
Pick-to: 6.5
Fixes: QTBUG-110933
Change-Id: I60bfc15c94133be368fa98ee1b3a0ab7a2bc53ef
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
There are many ways to "hide" the qmldir from the engine at run time,
which turns singletons into regular types. While all of this is invalid,
we should not assert on it, but rather produce a legible warning.
Furthermore, sharpen the importing of extra modules from qrc as implicit
imports. We should really only import modules the file in question can
ever be part of. Otherwise we needlessly produce the above situation and
hide legitimate warning messages.
Amends commit 7517c1b3ae.
Now we need to teach our tools about the default import paths in the
resorurce file system. They cannot guess any type they may find in any
resource file anymore.
Pick-to: 6.5
Task-number: QTBUG-106929
Change-Id: Ic8c02396d10830a7f461e8a81649bb8c9a1add1f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
qmlimportscanner is rather limited in how it works,
and does not pick up the Qt.labs.folderlistmodel
dependency for Dialogs.
Pick-to: 6.5
Fixes: QTBUG-103044
Change-Id: I778f5c8981f1a2603bc3a5d2fd249a83de6c9bd8
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Unfortunately value types behave differently when compiled to C++.
Document the difference and introduce a pragma to make them behave one
way or the other.
Pick-to: 6.5
Fixes: QTBUG-109221
Change-Id: Ib2685153c0b4ae209bafbea7a01229377fdb47dd
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
We can coerce QDateTime, QDate and QTime into each other because they
would all be represented by a Date object in JavaScript. Furthermore we
can coerce them all to QString. Technically, we could also coerce
strings to all of them, but we don't want to because that is terrible.
Fixes: QTBUG-109380
Change-Id: I176bfb5b715a6a6750cb5918c44261fa23fb8832
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
We should be able to compare QObject * with QObject * or a
nullptr.
Pick-to: 6.5
Fixes: QTBUG-109377
Change-Id: I0e9d6fdc89cbb471774d6382316dfb4813310e1d
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
The code generator currently rejects any comparisons other than
primitive types. Add comparison capability for var types against
null or undefined types and vice versa. To achieve this, we generate
code that fetches the contained object within the variant and
comparison is done depending on the stored type.
Ideally, we also need to add comparison capability for QObject *, that will be handled with QTBUG-109377.
Pick-to: 6.5
Fixes: QTBUG-108632
Change-Id: Ib15450d7922f6025c78def5cc548c74827ad740f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
We need to explicitly cast to double if we are wrapping a number type
that's not natively accepted by the ctors.
As a side effect, correctly run conversions from generic QVariant to
QJSPrimitiveValue through the engine now. For that we need another
clause in metaTypeFromJS().
Since we are calling methods that return list types in the test, we need
to add another clause that converts JS arrays to list types. Otherwise
we cannot run that test in interpreted mode.
Pick-to: 6.5 6.2 6.4 6.4.2
Task-number: QTBUG-109111
Change-Id: I87f7aafd24371d2c1ffe85569e1f2cd3a1979742
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
A StoreElement on a JS value can do pretty much anything you can
imagine, after all.
Pick-to: 6.5 6.4 6.4.2
Fixes: QTBUG-109196
Change-Id: Ic638d94b55e6340eb9fe56abc663a6f0f2277f5e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
If we try to lookup the length of a generic QVariant, we fail, and so
far crashed. We should ideally detect that we are dealing with an array
(and thus length is a known, available property), but for now simply
reject compilation to C++.
Pick-to: 6.4
Fixes: QTBUG-109164
Change-Id: I9d4149ac09a351754d012dbc829774413d6b32eb
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
We want to always import dependencies, always import qualified scripts,
and always try to load C++-based types from the binary. Furthermore,
directory imports should be imported with their qmldir URI where
possible, so that we can find them when loading local C++-based types.
Fixes: QTBUG-109109
Change-Id: I58f08f479623a886c802035b41f5f604338468b5
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
We obviously want to see the defaulted parameters when generating the
handlers.
Fixes: QTBUG-108762
Change-Id: I33a52bac305238467d45650bf8a2ad59d40e366f
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
We currently force the lookup metatype to be exactly the same data type
with the caller's. As a result, the conversion from enum to integral
data type is not recognized. Relax this comparison by using
isTypeCompatible helper.
Pick-to: 6.4
Fixes: QTBUG-109007
Change-Id: I188dc3e6c1fd7100e9ed5c4ba5d0c90d85d79be4
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
* If we got an object type exposed as namespace, we still need to add
the "*" to get its augmentedInternalName(). Otherwise we cannot get
its metaobject, needed to look up enums.
* Enums cannot be shadowed. The shadow check will produce garbage if we
try to check because an enum lookup also does not use the accumulator,
which then contains some artifact from a previous operation.
* If we find a property lookup on a plain QMetaObject* we have to
immediately return in order to not confuse it with attached
properties.
Pick-to: 6.4 6.2
Fixes: QTBUG-109048
Change-Id: If9e3b4806e4d773de9cf48f1b3750b684a8c8f69
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
If the local type is a namespace, the resulting type can only be a
namespace, too, no matter what kind of tag the foreign one has.
Furthermore, we can re-use types with other QML_* tags this way.
Task-number: QTBUG-108883
Change-Id: Ib2ae08d5b081b8faa35124314f97d406d7b4f76f
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
The same type can be exported multiple times with different attributes,
even in the same module.
This requires us to fix directory imports as qmllint otherwise complains
about SegFault.bad.qml and SegFault.qml being the same type (which they
obviously aren't).
Task-number: QTCREATORBUG-27590
Change-Id: I295d927b9a07acbb715055a6883ac44b50129c2d
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
We provide semi-private functions in the AOT context for this. Since we
cannot know the complete run time type of the potential logging category
at compile time, we have to check any first argument that might be one
separately.
Fixes: QTBUG-107175
Change-Id: I46a8922b1c5c16d2b450b8728d650d31dfd867e3
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Those are not stored. If we compare null to null or undefined to
undefined, we do not have to generate a comparison at all. the result is
statically known.
Pick-to: 6.4
Fixes: QTBUG-108634
Change-Id: I6a5323c2e0c023838609aec90d7ecc15b885dc08
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
When preparing for such a call, the byte code loads an "empty" constant.
This has to be represented in the type system so that we don't hit the
assert at the end of the instruction.
Pick-to: 6.4 6.2
Task-number: QTBUG-108441
Change-Id: I66220bfae3d3a4b8e9600d84d4cfc43ac858b77e
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
There are multiple types of signal indexes, one of them
belongs to QMetaMethod::signalIndex and another one to
QObjectPrivate::signalIndex.
Stop mixing them up in aot-compiled code when capturing
properties as this leads to weird and hard to debug bugs.
Add a smaller version of the drag and drop example as test
to make sure that the bug does not appear again, without any
visual elements.
Fixes: QTBUG-104047
Fixes: QTBUG-104716
Pick-to: 6.4 6.2
Change-Id: I4f64ba237e824ff0ba1624c29ddcf5371d03d69e
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
We don't discern between empty and undefined values in the compiler.
Fixes: QTBUG-104192
Change-Id: Ida06386433ef9e8f9a7cba4bec99ba8e77edc324
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Since lists are allowed as property types, you should be able to pass
them as arguments to methods, too. For now we only handle QML-defined
methods, implemented by adding JavaScript functions to your QML
elements. The usual type coercion rules apply if you pass JavaScript
arrays to such methods. That is, it usually works.
We now resolve properties with the "list" flag to their actual types
(QQmlListProperty or QList) already when populating the QQmlJSScope, and
store the list types as members of QQmlJSScope rather than as a special
map in QQmlJSTypeResolver. This allows us to do the same to lists passed
as arguments and simplifies some of the type analysis.
Fixes: QTBUG-107171
Change-Id: Idf71ccdc1d59f472c17084a36b5d7879c4d959c0
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
By default, the QML engine does not enforce signatures given as type
annotations to functions. By passing different types than the function
declares, you can get different behavior between the interpreter/JIT and
the AOT-compiled code. In addition, in interpreted or JIT'ed mode, we
pass all non-primitive value types as references. This means, if you
modify them within the called function, the modifications are propagated
back to the place where the value was loaded from.
Enforcing the signature prevents all of this, at a run time cost. Since
we have to coerce all arguments to the desired types, the function call
overhead grows. This change introduces a pragma
"FunctionSignatureBehavior" which you can set to "Ignored" or "Enforced"
to choose one way or the other as universal way of handling type
annotations.
Fixes: QTBUG-106819
Change-Id: I50e9b2bd6702907da44974cd9e05b48a96bb609e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
In case of an enum the actual contained type is the one the enum
dictates. This brings registerContains() in line with containedType()
and makes it possible to match previously discovered types on subsequent
passes of the type propagator. Therefore, it avoids infinite loops where
the same types would be tracked over and over.
Pick-to: 6.4
Fixes: QTBUG-107176
Fixes: QTBUG-107542
Change-Id: I4b8d66b157d0ec0ece4ca345cb99a630b8898a1b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
If we cannot access a property due to a version mismatch, that's not an
unqualified access.
Pick-to: 6.4
Fixes: QTBUG-107080
Change-Id: I1780b171928df437a2121601f1aac829dbe1e994
Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
With a particular nefarious combination of Q_GADGET and inheritance from
QObject you can make QmlCompiler believe a type is a value type even
though it is actually an object type. We never want to touch such a
thing.
There was a safe guard against this when looking up the type from the
scope, but by putting it in a type namespace you could circumvent it.
Refactor the code to apply to both cases the same way.
Pick-to: 6.2 6.3 6.4
Fixes: QTBUG-104556
Fixes: QTBUG-105608
Change-Id: I8a690e2b6f78fcaba0911a93504cde0d2c7dde0d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Some of the math operators were still missing. Add them and test them
all.
Since the "runInterpreted()" test function takes too long now, split the
qmlcppcodegen test in two: One that runs in compiled mode and one that
runs in interpreted mode.
Fixes: QTBUG-105188
Change-Id: I4b641d5e51b5a7e2a9254be40f257d7b249deb13
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
All of those are legal in ECMAScript, and so we need to support them in
script bindings. As we have stricter rules for literal bindings, add an
extra method there to check for what QQmlPropertyValidator does.
Pick-to: 6.4
Fixes: QTBUG-105252
Task-number: QTBUG-105188
Change-Id: I0621b2c3aa196414f669873e93670557284a8bca
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
So far we have only accepted QQmlListReference. However, we can also
pass a QQmlListProperty around as value.
Pick-to: 6.2 6.3 6.4
Fixes: QTBUG-105137
Change-Id: I7d4cd3048b62594298f91013c4cda5ec864a28df
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
CMakeLists.txt and .cmake files of significant size
(more than 2 lines according to our check in tst_license.pl)
now have the copyright and license header.
Existing copyright statements remain intact
Task-number: QTBUG-88621
Change-Id: I72c89a98c42bbc9234d8495e9e503bec81d11037
Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
If the signal handler does nothing but return a closure, we have to
compile the closure using the same signature as the outer signal
handler.
In order for this to work, we also have to detect unresolved argument
types for signal handlers. Those are just as bad as unresolved argument
types for other functions.
Fixes: QTBUG-101531
Change-Id: Idb5b3994809d91a4b4ce936282685435eb75e670
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>