Commit Graph

27 Commits

Author SHA1 Message Date
Maximilian Goldstein a9038a6cc6 QQmlJSLogger: Switch to an ID based system
This change makes qmljslogger use an ID based system for categorizing
logging entries instead of using an enum. This allows plugins to
register their own logging categories after the fact.

It's also necessary for us to later show the warning ID when
printing warnings and for creating documentation for each ID entry.

Currently not every ID maps cleanly to only one type of warning,
this has to be cleaned up in a follow-up change.

Task-number: QTBUG-103453
Change-Id: I4cac6be7ca165b938e0ea032d077823bf17baf75
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-06-30 11:23:36 +02:00
Thiago Macieira 067d5a3334 QQmlJSLogger: disable warning from GCC 11 & 12
I think it's coming from the push_back in QQmlJSLogger::log(), but GCC
appears to require the warning be suppressed at the template, not the
instantiation point.

GCC 11:
qarraydataops.h:581:11: error: ‘*(QArrayDataPointer<FixSuggestion::Fix>*)((char*)&tmp + offsetof(Message, Message::fixSuggestion.std::optional<FixSuggestion>::<unnamed>.std::_Optional_base<FixSuggestion, false, false>::<unnamed>)).QArrayDataPointer<FixSuggestion::Fix>::ptr’ is used uninitialized [-Werror=uninitialized]

GCC 12:
qarraydataops.h:581:11: error: ?*(QArrayDataPointer<FixSuggestion::Fix>*)((char*)&tmp + offsetof(Message, Message::fixSuggestion.std::optional<FixSuggestion>::<unnamed>.std::_Optional_base<FixSuggestion, false, false>::<unnamed>)).QArrayDataPointer<FixSuggestion::Fix>::d? may be used uninitialized [-Werror=maybe-uninitialized]

Pick-to: 6.2 6.3 6.4
Change-Id: I0e5f6bec596a4a78bd3bfffd16c995116afc2718
Reviewed-by: Marc Mutz <marc.mutz@qt.io>
2022-06-15 18:09:55 +00:00
Lucie Gérard 0dc4fd240a Use SPDX license identifiers
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>
2022-06-11 08:05:15 +02:00
Sona Kurazyan 2c9c1590e6 Replace uses of deprecated _qs with _s/QStringLiteral
Task-number: QTBUG-101408
Change-Id: Ic925751b73f52d8fa5add5cacc52d6dd6ea2dc27
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-04-29 09:47:43 +02:00
Maximilian Goldstein 7c9276d38b qmllint: Integrate plugin infrastructure
Integrates the plugin and pass infrastructure into qmlcompiler and qmllint proper.
Plugins are searched for in the "qmllint" subfolder of the Qt installation's plugin
directory. In addition we also support loading statically linked plugins.

[ChangeLog][qmllint][New Feature] qmllint can now be extended via plugins. Use --plugins
to get a list of available plugins.

Original-patch-by: Fabian Kosmale <fabian.kosmale@qt.io>
Change-Id: I75a09dd978fc7724aca4931f055cc71c7ced971b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-04-05 14:06:56 +02:00
Maximilian Goldstein 651bf47ab3 qmlcompiler: Implement structured QML static analysis
This patch adds the qqmlsa "framework", which is meant as a starting
point for a more structured, extendible static analysis for QML.
While qmllint (or rather, the QQmlJSImportVisitor used by it) can
already do quite a few checks internally, it is hard to extend.
Moreover, the checks there are interspersed with parsing code, and might
run before all types are resolved. We also do not want to add check that
are specific to QtQuick, Controls, Quick3D... into the core QtQml
module. This poses quite a few challenges: For instance, the color in
QML resolver depends on QtQuick/QtGui to check whether a string is
actually a color.

To overcome the issues mentioned above, we introduce the concept of
analysis passes, and a PassManger class. Passes can come in two shapes
currently:
- PropertyPasses run on each property that has a binding assigned to it
- ElementPasses run on each (sub-)object instantiated in the file
  A property can have multiple bindings assigned to it (due to e.g.
  Interceptors, but also for list properties). Therefore we pass a list of
  them to the ElementPass.
  Passes which only want to handle the "normal" case of one binding per
  property can use SimpleElementPass, which for now just takes the first
  property in the list.
Passes have a pure virtual run function, in which the actual work is
done. They also have a filter function, which in the default
implementation simply returns true, which means that the pass will run.
The filter function is there to make writing passes a bit more
structured, by separating the "do I need to analyze this" question from
the actual analysis part.

To solve the issue of library dependencies, we expose a plugin interface
that then returns passes to be run based on the root component.
Then, user can create a plugin implementing the interface,
which we will load the plugins from a known location, and register all
of them. This will be implemented in the next patch in this set.

Limitations:
- The current passes cannot touch the IR, and thus cannot
  really analyze what happens in script binding.
- (inline) components are currently badly handled
- QQmlJSScope has various issuse with grouped properties

Fixes: QTBUG-101604
Original-patch-by: Fabian Kosmale <fabian.kosmale@qt.io>
Change-Id: Ic96259a947fbb17f79aa58ca613c8d0905a9a74c
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-03-29 13:28:04 +01:00
Maximilian Goldstein 195af3ce69 qmlcompiler: Allow for logging other files and add auto-fix infrastructure
This change makes sure the logger can write messages and show excerpts
from files other than the current one. This is necessary in order to
give users hints about problems that arise due to other components.

It also adds a field to FixSuggestion::Fix which specifies whether a
suggested fix can be applied automatically or is only a hint.

Change-Id: I94a929d3fc3fc966591cffb99e67309d264c38e7
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2022-03-03 11:19:51 +01:00
Maximilian Goldstein 31abba8cdc qmlcompiler: Suggest fix for multiline strings
We can now suggest a template string to use instead that is properly
escaped. Once auto-fixing becomes available we can automatically replace
deprecated multiline strings with the new suggestion.

Task-number: QTBUG-92448
Change-Id: I4e77820b66ae960cde558a62689c5da328b8df5b
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
2022-03-02 14:21:08 +01:00
Andrei Golubev 690b7cb6a2 Redesign QQmlJSLogger internals
High-level goal: be able to reuse existing infrastructure
"as is" to configure semantic analysis categories in tools
(qmllint, qmltc, qmlsc, etc.)

To achieve that, simplify the logging to always "log"
something, without explicitly specifying the severity. The
severity is now baked into the category (and we can extend
those to cover different cases)

One slight deviation is the cache generation which likes
to do its own thing at present. Provide a "forced logging"
option where we can specify which severify we want. The
hope is that this gets removed at some point

Particular list of (noteworthy) changes:
* No more "thresholding" by the level (this is rarely needed
  and is actually questionable). Instead, we can ignore a
  particular category explicitly
* Category levels are repurposed as category severities
  (at least from the high-level picture that always should've
  been this way)
* log{Warning,Info,Critical} removed. We use category severity
  instead
* "category error" makes zero sense so removed: if our severity
  is:
  - QtWarningMsg (qmllint), it is already an "error"
  - QtCriticalMsg (compilers), it is already an "error"
* Align m_output and m_{infos,warnings,errors} stored information
* Accept the fact that we don't support QtDebugMsg and QtFatalMsg
* Additional categories added to cover for places where the same
  category would be both an error and not an error

Task-number: QTBUG-100052
Change-Id: I3cd5d17d58be204f48428877bed053f756ac40a8
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2022-02-12 23:21:29 +01:00
Maximilian Goldstein 52c09a27ef qmllint: Use fix suggestions in a more structured way
Fix suggestions are now attached to the warnings they are caused by
and are also accessible via JSON.

This allows us to use the qmllint library for more of tst_qmllint,
greatly improving performance.

Change-Id: Idd0398028bff1272a75dc1193d2c15a25d335dbf
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-12-10 17:11:05 +01:00
Maximilian Goldstein 46f397775e tst_sanity: Also handle ids via qmllint
Utilize our warning against using ids on deferred properties instead
of the id visitor.

To accomplish this cleanly we have to move our deferred property
warnings into a different category.

Also remove the BLACKLIST since the corresponding tests no longer exist
and the qmllint version of them does not require any blacklisting.

Fixes: QTBUG-96021
Change-Id: I35f88157c9c4aa20e006f09a1402e3100fe09fb9
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-11-30 19:42:54 +01:00
Ulf Hermann e551331f38 Add a default implementation for QQmlJSAotCompiler
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 <fabian.kosmale@qt.io>
2021-11-29 23:12:45 +01:00
Maximilian Goldstein 608e1a8053 qmlcompiler: Use QT_BEGIN_NAMESPACE / QT_END_NAMESPACE everywhere
Some code was not properly wrapped in a namespace.

Change-Id: If70fd9782391309c511b66ae01eae43cb36292ac
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-11-23 18:45:02 +01:00
Ulf Hermann c8f967f547 qmllint: Force fix suggestions to use QtInfoMsg
It makes no sense to use a higher message level for a fix suggestion. A
fix suggestion should be prefixed by the warning or error that triggers
it. That warning or error should have the actual level.

Change-Id: I4b5a2ec150afd469ea53697546541a7890c525ec
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-11-23 18:06:59 +01:00
Maximilian Goldstein e01ede4378 qmllint: Add ability to warn about not reusing attached types
This is mostly useful as an replacement for Quick Controls' tst_sanity but might also be useful in some other instances.

Fixes: QTBUG-96572
Change-Id: I5cf414bfeb369cbc394563c5c5ed807599b09a2f
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-09-29 19:48:51 +02:00
Maximilian Goldstein 83f918b005 qmllint: Add ability to warn about function declarations
Another warning ability we need in order to replace controls' tst_sanity with something more sensible.
Probably not useful outside of that, so it is disabled by default.

Fixes: QTBUG-96573
Change-Id: I6241899f167f7ea5463ff5b3f157c616c1936cd2
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@qt.io>
2021-09-24 14:23:42 +02:00
Fawzi Mohamed b69267d429 qmlcompiler: enable standalone building:
- convert to string to in a couple of places to work without
QStringView + operator
- import local files with "*" (not via <private/*>)

Change-Id: I1d7cdcbd39e609f36693733e98d4f74a7260ce88
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-08-31 13:51:06 +02:00
Maximilian Goldstein 67894892da qmllint: Integrate type inference warnings
This change helps bring in type inference and compiler warnings previously only generated by qmlcachegen+.
These warnings are disabled by default and have to be enabled manually via the --compiler option.

Also makes the logger handle zero length SourceLocations properly by just highlighting the entire line instead of hitting an assert.

Change-Id: Iebad6e9236214d9367f97487e7b5787592edab7d
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-07-07 14:03:21 +02:00
Maximilian Goldstein 3b3d0c6f3c qmllint: Implement severity levels
qmllint now supports logging levels of different severities. Still lacking a good way to toggle the verbosity more granularly though (i.e. disabling only info messages while still receiving the rest).

Change-Id: I71abddcdf1adf60315a87d776af8085acf7aeffe
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-07-02 17:25:21 +02:00
Maximilian Goldstein 3b28a298b0 qmllint: Formalize fix suggestions
They are now handled by the logger instead of being done by external classes using the ColorOutput directly.
This will allow for modernizing the logger and for automatically applying those suggested fixes.

Fixes: QTBUG-94170
Change-Id: I90b960d22cb91203b8e8a5c69b0fdaf6fca2fc0c
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
2021-07-01 18:08:00 +02:00
Maximilian Goldstein 9f389ee75d qmllint: Add ability to ignore individual warnings
Allows users to ignore individual warnings by adding a "// qmllint disable" comment in the line that triggers the warning.
This feature is especially useful for use in pre-commit / CI tests as it allows to add exceptions for individual warnings that cannot be fixed immediately.

[ChangeLog][qmllint][New Feature] You can now ignore individual warnings by adding "// qmllint disable"
in the line causing it. You may also specify one or more warning type to ignore ("// qmllint disable warningtype1 warningtype2...") which is preferable. This can also be done for entire blocks of code by using "// qmllint disable" in an empty line and ending it with "// qmllint enable"

Change-Id: Iea6c29132d6b51ecfb5e5d8a19a43446a7286c24
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-06-03 08:54:57 +02:00
Maximilian Goldstein 73d51eed2f qmllint: Add support for loading options from settings
This change adds support for a reading a simple settings file (.qmllint.ini) to set log levels and various other options.
The settings file applies on a per-directory basis so linting files in two subdirectories with different settings will use their respective settings files.
If the directory of the linted file does not contain any settings we search through all parent directories.

This is implemented in a way that qmlformat can also utilize the settings file code.

This makes qmllint more useful for larger projects that might want different settings for different parts of their QML code.
It also allows for better integration in CI checks and pre-commit hooks.

[ChangeLog][General][qmllint] Adds the ability to set linting options via a settings file rather than using command line parameters. Use --write-defaults to generate a template with default values for editing. Use --ignore-settings to disable this feature

Change-Id: I94e4a47916b5dfd16c3a69efdba3858235cab738
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-05-27 11:30:12 +02:00
Maximilian Goldstein 04c2546b82 qmllint: Add inline component support
Adds support for inline components for qmllint with a few things not working yet:
- Two inline components referencing each other
- Using inline components before they are declared

These two issues require a larger overhaul of qmllint as a whole and will be addressed in a different change.

Change-Id: I2834702c21a8eb728db4709d6f475c33796b3e4d
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-05-14 16:39:40 +02:00
Maximilian Goldstein c44b350bf6 qmllint: Warn about multiline strings
Task-number: QTBUG-92448
Change-Id: Ic6305f05cb8a0af5c36ac03d8b541ac78cea0612
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-04-20 14:36:07 +02:00
Maximilian Goldstein 7a9b84ca6d qmllint: add options for setting logging levels
Add the ability to individually disable and set the severity of all warnings produced by qmllint.

Change-Id: I46081f8b37fb90f8d0f4a5f2f08223d7b7285041
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
2021-04-09 15:26:52 +02:00
Maximilian Goldstein 3fde335a52 qmllint: Improve import warnings
Import warnings will now always be clearly associated with the line and import that
caused them. They're also visually separated now and don't redundantly show the importing files name in every warning.
Some type of imports such as file or URI based imports never had their warnings processed which is also fixed by this change.

Change-Id: I63d720fcf198ff5302c2566a91cde4c716697f7e
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-03-30 17:42:06 +02:00
Maximilian Goldstein 954071f372 qmlcompiler/qmllint: Use unified logger
Improves the logging situation greatly by allowing all logging messages to be assigned different severities,
highlighting the code that caused them and by now ensuring a qmllint warning will always result in a non-zero exit code.

A later patch will expose more of these options to the user.

Change-Id: Id9b036fe3ba80dd18e9f8cb1b05efa891713d5a8
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
2021-03-29 12:31:01 +01:00