1// Copyright (C) 2023 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
5 \page qtqmlcompiler-index.html
7 \brief Provides tools for static analysis of QML code.
9 The Qt QML Compiler module offers the QQmlSA framework which provides tools
10 for static analysis of QML code. These tools can help ensure syntactic
11 validity and warn about QML anti-patterns.
13 Adding static analysis to a QML program is done by writing plugins. They
14 will run a collection of analysis passes over the elements and properties
15 of the QML code. The passes can be registered with a PassManager which
16 holds the passes and can be called to analyze an element and its children.
18 A pass is a check for a certain rule or condition evaluated on elements or
19 properties. If the condition is met, the pass can warn the user of an
20 indentified issue in the code and maybe even suggest a fix. It is called a
21 pass because the analysis performed on elements and properties happens by
22 running a collection of passes on them in succesion. Each pass should be
23 responsible for identifying one specific issue only. Combining a set of
24 passes can perform more complex analysis and, together, form a plugin.
26 Element passes are defined by two main components, namely \c shouldRun()
27 and \c run(). When performing the analysis, the pass manager will execute
28 the pass over every element it encounters while traversing the children of
29 the root element. For each element, if \c shouldRun() evaluated on that
30 element returns \c true then \c run() is executed on it.
32 Passes on properties trigger on three different events, namely when the
33 property is bound, when it is read, and when it is written to. These can be
34 implemented by overriding the \c onBinding(), \c onRead() and \c onWrite()
35 functions respectively.
37 As the code grows, so does the number of elements and properties.
38 Performing the static analysis passes on all of them can become expensive.
39 That's why it is good to be granular when deciding which elements and
40 properties to analyze. For elements, the \c shouldRun() is intended to be a
41 cheap check to determine if \c run(), which performs the real computation,
42 should be run. For properties, the selection is done when registering the
43 passes with the manager. The \c registerPropertyPass() function takes the
44 \c moduleName, \c typeName and \c propertyName strings as arguments. These
45 are used to filter down the set of properties affected by the registered