aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsfunctioninitializer.cpp
Commit message (Collapse)AuthorAgeFilesLines
* qqmljsfunctioninitializer: initialize all argument typesSami Shalayel2025-05-161-2/+2
| | | | | | | | | | | | | Initialize all argument types even if we already warned about the missing type annotation. This allows to get correct types in QQmlJSTypePropagator later on during linting. Amends 06577c9e80eb150b6b9e76e7805bfed1abbae82d. Pick-to: 6.9 Change-Id: Ieaad973f411d5b0f914561d95dfab72175563e15 Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Clean up error handlingUlf Hermann2025-02-021-28/+15
| | | | | | | | | | | | | | | | We should only have one way to handle diagnostic messages: The QQmlJSLogger. In addition each compile pass may result in an error that prevents the running of further passes. But that error should not rely on the selection of messages posted earlier. For this to work we need to introduce a further state transition into the logger. The logger now "archives" messages after compiling each function, so that only the current function's compile errors are taken into account as result of the current function's compilation. Task-number: QTBUG-124913 Change-Id: I4b6d9910b80527cefb1aba02598114d1fe5ba172 Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Do not post-process compile errorsUlf Hermann2025-01-241-13/+27
| | | | | | | | | | We can determine the correct QtMsgLevel and prefix early on and set that right away. Doing so will allow us to use the logger also for compiler errors and remove the extra list of messages in a second step. Task-number: QTBUG-124913 Change-Id: I145be21d0a210f07245aa19e3124634cdd4800b2 Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Reduce duplication of warnings about missing propertiesUlf Hermann2025-01-171-55/+48
| | | | | | | | | | | | If a property cannot be found, we don't need to check its type or even try to compile a binding for it. We also shouldn't claim a property doesn't exist if we cannot find it. We may have failed to resolve the type after all. Pick-to: 6.9 6.8 Task-number: QTBUG-124913 Change-Id: I93ef12e888762ae03f8fa6b1bef2e8d04ba3d4b2 Reviewed-by: Sami Shalayel <[email protected]>
* QmlCompiler: Improve naming of QQmlRegisterContentPool methodsUlf Hermann2024-12-031-2/+2
| | | | | | | The name should say what kind of QQmlJSRegisterContent it creates. Change-Id: Ia77bfc7c2a34395ca9e54ba496acd9d6883152cb Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Track function signature types only onceUlf Hermann2024-12-031-14/+6
| | | | | | | | | namedType() already creates a fresh QQmlJSRegisterContent. There is no need to clone it right away. Task-number: QTBUG-124670 Change-Id: I7a669df3a8cd2992afde20037d9400fd8ed8253b Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Remove trivial type comparison methodsUlf Hermann2024-11-291-1/+1
| | | | | | | | We can compare types without QQmlJSTypeResovler now. Task-number: QTBUG-124670 Change-Id: Id06c8cd5cc8f03683134ad13e02d54ae4da9fae3 Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Split QQmlJSRegisterContent in public and private classesUlf Hermann2024-11-201-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | We want an easy way to hold pointers to other QQmlJSRegisterContents in QQmlJSRegisterContent. Furthermore, copying a QQmlJSRegisterContent so far is very expensive. Solve both problems by introducing the PIMPL pattern with a shared d-pointer. This also changes the equality semantics of QQmlJSRegisterContent. Two QQmlJSRegisterContents are only equal if they contain the same d-pointer now, not if their contents are otherwise equal. However, since we generally don't rely on immediate equality of QQmlJSRegisterContent anyway, this is not a problem. QQmlJSTypeResolver::equals() still works. There is one place where the equality was used, though. That one is adapted. Furthermore, we now want to keep the register contents in a pool that's automatically cleared when we're done with our analysis. Therefore the creation methods cannot be static anymore and storedIn() as well as castTo() need to go through the pool as well. Task-number: QTBUG-124670 Change-Id: I0a51b609fc769ccb33c1d82930bda83c2a40e1a5 Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Mark types in function signatures as "named"Ulf Hermann2024-10-171-8/+9
| | | | | | | | | | We have the TypeByName content variant already for the related concept of naming a type in script code, for example to perform a type assertion. We can re-use it for signatures. Task-number: QTBUG-124670 Change-Id: If13518df2b2217769d02c4618f57203907b3f5f9 Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Simplify content variants for QQmlJSRegisterContentUlf Hermann2024-10-121-2/+6
| | | | | | | | | | | Instead of having a cross product of "scope" and "object" on the one hand and "property", "method" and "enum" on the other hand, use the scopeType to resolve what kind of element a property, method or enum belongs to. Task-number: QTBUG-124670 Change-Id: Ia9db05e13979e55e0ed7912afc2003dfd018987a Reviewed-by: Olivier De Cannière <[email protected]>
* QmlCompiler: Fix various coverity warningsUlf Hermann2024-09-031-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | Pass values by const ref or move them, but don't pass them as copies. Coverity-Id: 467911 Coverity-Id: 467912 Coverity-Id: 467913 Coverity-Id: 467914 Coverity-Id: 467915 Coverity-Id: 467916 Coverity-Id: 467917 Coverity-Id: 467918 Coverity-Id: 467919 Coverity-Id: 467920 Coverity-Id: 467921 Coverity-Id: 467922 Coverity-Id: 467923 Coverity-Id: 467924 Coverity-Id: 467925 Coverity-Id: 467926 Coverity-Id: 467927 Coverity-Id: 467928 Change-Id: I1549e1f3365c6becc330603959a71b2058e1b1fa Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Compiler: Create infrastructure to support multiple warningsOlivier De Cannière2024-08-211-19/+17
| | | | | | | | | | | | | | | | | Currently only one DiagnosticMessage can be stored at a time when using the compiler. However, we want to be able to show more than one to the user. Therefore, use a list that gets passed inside the compiler instead of a pointer to the sole error. This also means that the error is valid by its very existence. There is no need to check validity explicitly anymore. Task-number: QTBUG-127624 Change-Id: I356db917b86703b508dc1ad52de7825d82eafd71 Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Sami Shalayel <[email protected]>
* Compiler: Only warn about missing type annotation once per functionOlivier De Cannière2024-08-211-4/+8
| | | | | | Change-Id: I6f9788c906158e549e57c04223ae10d5a789ecec Reviewed-by: Sami Shalayel <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Divide scope-name lookup methods into multiple casesUlf Hermann2024-06-151-2/+2
| | | | | | | | | | | | | | | | | * One method for IDs only, since that seems to be common * One method operating on QQmlJSRegisterContent all the way * One method operating on QQmlJSScope::ConstPtr all the way This way we can return a QQmlJSScope::ConstPtr where we are not interested in register contents, and in a next step, link the register contents together in case we are interested. We need to store the function's QML scope as QQmlJSRegisterContent now. Task-number: QTBUG-124670 Change-Id: I01699aaa5f645657d9faf23b12e270cf09679499 Reviewed-by: Alexei Cazacov <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QtQml: Properly enforce signatures of AOT-compiled functionsUlf Hermann2024-04-261-6/+7
| | | | | | | | | | | | | Pass the metatypes of the contained types rather than the stored types. [ChangeLog][QtQml][Important Behavior Changes] The AOT compiled code for type-annotated JavaScript functions does not let you pass or return values of the wrong type anymore. Fixes: QTBUG-119885 Change-Id: I685d398c0745d32a999a3abd76c622a2c0d6651f Reviewed-by: Olivier De Cannière <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Replace signal name manipulations with QQmlSignalNamesSami Shalayel2023-08-151-32/+35
| | | | | | | | | | | | | | | Remove custom implementations found in qqmljs* and use the static helper methods from qqmlsignalnames_p.h instead. This sometimes requires to move some code around to avoid bugs with property that do not have letters in their name. Add a warning in the JS implementation of the SignalSpy.qml that the used heuristic might fail on certain signal names. Add tests in in tst_qqmllanguage to see if the property change handlers work correctly for weird names. Change-Id: I4dc73c34df7f77f529511fa04ab5fcc5385b59fc Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* qmllint: Complain if function without return type returns somethingUlf Hermann2023-06-221-0/+6
| | | | | Change-Id: I3058ebe82d84d6e6cd62f38a01dc61e9c3f46787 Reviewed-by: Sami Shalayel <[email protected]>
* QQmlSA: Create an abstraction layer for static analysisOlivier De Cannière2023-05-301-1/+1
| | | | | | | | | | | | | | | This patch adds abstractions for QML Elements, Bindings, Methods and Properties. This abstraction layer avoids exposing internal details and should be more suited for static analysis tasks. It is now possible to write qmllint plugins without including private headers. As a drive-by, change tst_qmllint:verifyJsRoot to open files in text mode instead of binary. This fixes an issue where line endings cause issues on Windows. Fixes: QTBUG-102276 Change-Id: I6b6e53f1e0078734a18f3aa51807fbe875b375f0 Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Add hint about generalized grouped propertiesUlf Hermann2023-02-031-3/+9
| | | | | | | | | | | If a property cannot be found but there are immediate properties in the surrounding type, that indicates that the construct in question may be phrased using generalized grouped properties. Pick-to: 6.5 Fixes: QTBUG-105251 Change-Id: I107132294ba0ca56ff522fc29e7a1972553390bd Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Ignore cloned signals when analyzing signal handlersUlf Hermann2022-12-071-0/+2
| | | | | | | | | We obviously want to see the defaulted parameters when generating the handlers. Fixes: QTBUG-108762 Change-Id: I33a52bac305238467d45650bf8a2ad59d40e366f Reviewed-by: Fabian Kosmale <[email protected]>
* QQmlJSMetaParameter: Encapsulate parameter informationSami Shalayel2022-12-021-5/+5
| | | | | | | | | | | | | | | | | | | Previously, there were four lists that contained each one entry for each parameter. There was one list responsible for the names, types, type names and const-qualifiers but this was quite bothersome to use (e.g. they not always had the same length). This commit introduces QQmlJSMetaParameter to encapsulate all the information required when manipulating parameters. This reduce the 4 lists to one, making parameters easier to handle and QQmlJSMetaMethod easier to read. This is a purely refactoring change, no new functionality was added. Task-number: QTBUG-107625 Change-Id: Ia41b823c9e6294ee26e828071b802cac6b4058ce Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Ulf Hermann <[email protected]>
* QmlCompiler: Allow lists as arguments to methodsUlf Hermann2022-11-101-6/+5
| | | | | | | | | | | | | | | | | | | 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 <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* Add option to enforce function signaturesUlf Hermann2022-10-141-0/+6
| | | | | | | | | | | | | | | | | | | | | 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 <[email protected]>
* Port from qAsConst() to std::as_const()Marc Mutz2022-10-071-1/+1
| | | | | | | | | | | | | | 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 <[email protected]>
* 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 <[email protected]>
* QmlCompiler: Handle trivial signal handler constructionsUlf Hermann2022-07-071-5/+33
| | | | | | | | | | | | | | 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 <[email protected]>
* QmlCompiler: Initialize registers with undefined where necessaryUlf Hermann2022-07-051-0/+6
| | | | | | | | | | | If we read the initial state of a register, we need to make sure it actually exists at that point. Uninitialized variables are implicitly undefined in JavaScript. Pick-to: 6.4 Task-number: QTBUG-104687 Change-Id: Ide4fe429b10ec28dcf267e7d34c6316355b16baa Reviewed-by: Fabian Kosmale <[email protected]>
* Use SPDX license identifiersLucie Gérard2022-06-111-27/+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 <[email protected]>
* Reimplement PropertyPass to evaluate bindingsMaximilian Goldstein2022-05-161-4/+3
| | | | | | | | | | | | | | | | | | | | | | This change reimplements the PropertyPass to be based on bindings rather than on just iterating over elements. This is a lot less cost intensive than iterating over all properties regardless of whether they are actually used. You may still achieve the same thing with the more flexible element pass, just with the benefit that you can choose what properties you want to iterate over instead of iterating over all of them. To demonstrate the passes usefulness the existing attached property warnings are ported to use the binding pass and can now also warn when an attached property is read or written in a context where it's not supposed to be used. Fixes: QTBUG-102860 Fixes: QTBUG-102418 Task-number: QTBUG-102859 Change-Id: Iea87a1b05b954429b8bf00fd27b60487940af679 Reviewed-by: Ulf Hermann <[email protected]> Reviewed-by: Qt CI Bot <[email protected]>
* QML: Port QV4::CompiledData::Binding to new special integer bitfieldUlf Hermann2022-05-111-3/+3
| | | | | | | Pick-to: 5.15 6.2 6.3 Task-number: QTBUG-99545 Change-Id: I9f8bc5fa45c61f77ee95b055a3d8de001da8f8c5 Reviewed-by: Fabian Kosmale <[email protected]>
* QML: Port QV4::CompiledData::Location to new special integer bitfieldUlf Hermann2022-05-111-2/+2
| | | | | | | | Pick-to: 5.15 6.2 6.3 Task-number: QTBUG-99545 Change-Id: If0d6f893f2351a4146ddf125be4079b5e312f308 Reviewed-by: Fabian Kosmale <[email protected]> Reviewed-by: Sami Shalayel <[email protected]>
* Replace uses of deprecated _qs with _s/QStringLiteralSona Kurazyan2022-04-291-21/+23
| | | | | | Task-number: QTBUG-101408 Change-Id: Ic925751b73f52d8fa5add5cacc52d6dd6ea2dc27 Reviewed-by: Ulf Hermann <[email protected]>
* QmlCompiler: Implement generate_DefineArrayUlf Hermann2022-03-141-1/+1
| | | | | | | | | | | Using the type cloning and adaption mechanism we can now determine what kind of list we have to create in order to avoid a later conversion. We can even propagate the type adjustment into the element types we read. Fixes: QTBUG-100157 Change-Id: Ia2f160ebae56f39ee5946f49d2f8c5b4986a6b77 Reviewed-by: Qt CI Bot <[email protected]> Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Store arguments as QQmlJSRegisterContentUlf Hermann2022-03-031-4/+8
| | | | | | | | This way we can uniquely track the stored types throughout the compilation. Change-Id: Ibf3814a37f105c2eede2a08f547ab5fbfa1c16e2 Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Prepare QQmlJSTypeResolver for in-place type manipulationUlf Hermann2022-02-241-3/+4
| | | | | | | | We need quite a few more methods for this. The methods will be taken into use in follow up changes. Change-Id: I94e9f5b5fb3da277d90ea040b0219585ba6df397 Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: track register contents by cloning typesUlf Hermann2022-02-161-3/+4
| | | | | | | | | | | Whenever we write a register, we create a new type. This way, whenever we determine that a different type would be a better fit at that place, we can just change the type in place, without affecting any unrelated code. Task-number: QTBUG-100157 Change-Id: I70be2eb83bda5483e083f58113fdfe57224b237e Reviewed-by: Fabian Kosmale <[email protected]>
* QmlCompiler: Allow assigning empty lists to list propertiesUlf Hermann2022-02-141-1/+5
| | | | | | | | Generate an empty list when creating a list with 0 elements. Task-number: QTBUG-100157 Change-Id: I3b0fe0b737a8ec5257785ae32231f4b687d3b204 Reviewed-by: Fabian Kosmale <[email protected]>
* qqmljstypepropagator: Use variant type for arguments of unknown typeMaximilian Goldstein2021-12-131-0/+2
| | | | | | | | | | | | Previously those function arguments would result in an invalid type being used which lead to crashes when invoking methods using those arguments. Pick-to: 6.3 Fixes: QTBUG-99027 Change-Id: I27e643f2512e1542d766b5fe98adfee043245c6f Reviewed-by: Andrei Golubev <[email protected]> Reviewed-by: Ulf Hermann <[email protected]>
* QmlCompiler: Fix return type calculationUlf Hermann2021-12-061-1/+2
| | | | | | | | | | We can return void from a function, explicitly or implicitly, and we need to be able to wrap that into a QVariant. In order to explicitly return void, we need the void type to be exposed and understood. Pick-to: 6.2 Change-Id: I513cabb25469b89a85b5d212a6825a037400729d Reviewed-by: Fabian Kosmale <[email protected]>
* Add a default implementation for QQmlJSAotCompilerUlf Hermann2021-11-291-0/+236
The default AOT compiler compiles QML code in indirect, dynamic mode. It uses the logger's Log_Compiler category to determine the verbosity of its output. In addition you can use the qt.qml.compiler.aot category for even more verbosity. In preparation for using QQmlJSAotCompiler with qmlcachegen, the default level of that category is increased to QtFatalMsg. The highest level we actually output is QtDebugMsg, so it doesn't make a difference yet. If the logger's Log_Compiler category is set to produce errors, it will qFatal() on "pragma Strict" violations. Change-Id: Ieb74bfa7cd51cfa8616792ab467c32f6ba0e0702 Reviewed-by: Fabian Kosmale <[email protected]>