// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
\page qtqml-qtquick-compiler-tech.html
\ingroup overviews
\title Qt Quick Compiler
\brief Overview of Qt Quick Compiler components

Qt Quick Compiler lets you process QML and JavaScript code at compile
time, rather than at run time. This allows for:

\list
    \li Faster application startup
    \li Faster evaluation of bindings and functions
\endlist

The Qt Quick Compiler consist of two components:
\list
    \li \l {QML type compiler}
    \li \l {QML script compiler}
\endlist

\note \e qmltc, \e qmlsc and \l qmlcachegen are internal build tools. If you
need to care about their invocation, you are either writing a build system, or
you are doing something wrong.

\section1 The QML type compiler

The \l{QML type compiler}, \e(qmltc) compiles QML types to C++ classes. These C++
classes are then added to your application and can be instantiated from other
C++ code. This way you can avoid much of the overhead of using \l{QQmlComponent}
to create instances of your QML types. In order to benefit from \l qmltc, you
need to adapt your C++ code and make use of the new classes.

\l qmltc can only compile a QML document if it completely understands its
structure. It will fail if an unsupported language feature is encountered.
It does not have to understand the JavaScript code in bindings and functions,
though.

\section1 The QML script compiler

The \l{QML script compiler}, (\e qmlsc and \e qmlcachegen) compiles bindings and
functions to both, an efficient byte code and C++ functions. This process
automatically happens behind the scenes if you are using \l{qt_add_qml_module}
to specify your QML modules. For more information about available options to
control different aspects of QML compilation, see
\l {Caching compiled QML sources}.

At compile time, for each QML or JavaScript
document a corresponding C++ file is created and built into the application. The
C++ file then contains a \e{QML compilation unit}, which consists of:

\list
    \li An efficient representation of the document structure
    \li Byte code for all functions and bindings in the document
    \li C++ code for functions and bindings the compiler fully understands
\endlist

The QML engine then refrains from compiling the QML or JavaScript source code
at run time and instead uses the pre-built compilation unit to load the QML
component and its functions and bindings more quickly. The functions and
bindings that were compiled to C++ can also be executed faster. Other bindings
and functions are either interpreted directly from the byte code, or compiled
to machine code via a JIT compilation step at run time. At compile time, more
involved type analysis can be performed. Therefore, the generated C++ code
is generally more efficient than the result of the JIT compilation.

There are limitations on what JavaScript constructs can be compiled to C++.
For more information on these limitations, see
\l {Limitations when compiling JavaScript to C++}. For statistics on how well
a QML project can be compiled, see
\l {Obtaining statistics about the compilation of functions and bindings}.


\e{qmlsc} will be used instead of \e{qmlcachegen} if the Qt Quick Compiler
Extensions are installed. It has the following additional features over
\e{qmlcachegen}:

\list
    \li It can compile documents in Direct Mode. In that case, the C++ headers
        of the types underpinning other QML components are directly included
        and the methods of those types are directly called. Conversely, in
        Indirect Mode, \e qmlcachegen or \e qmlsc call methods through the
        lookup mechanism which is also used in the interpreter and JIT.
    \li It can compile documents in Static Mode. In that case, \e qmlsc assumes
        that no properties of any types exposed to C++ can be shadowed by
        derived types. This allows for more bindings and functions to be
        compiled, but generates invalid code if any properties are shadowed.
\endlist

Instead of producing C++ as output, \l {qmlsc} and \l {qmlcachegen} can also
generate .qmlc, .jsc and .mjsc "cache files". These still contain a QML
compilation unit each, and can be loaded by the QML engine to avoid
re-compilation. They can only contain document structure and byte code, though.
Compilation of bindings and functions to C++ is omitted if cache files are
produced. Neither the CMake nor the qmake build system offered by Qt expose this
functionality.

\section1 Summary

The following table summarizes the differences between \l{qmltc},
\l{qmlcachegen} and \l{qmlsc}:

\table
    \header
        \li \e qmltc
        \li \e qmlcachegen
        \li \e qmlsc
    \row
        \li Compiles QML types to C++ classes
        \li Compiles QML documents to QML compilation units
        \li Compiles QML documents to QML compilation units
    \row
        \li Generated output acts as faster alternative to
            \l{QQmlComponent}-based object creation.
        \li Generated output is used internally by the QML engine to avoid
            re-compilation, and to speed up execution.
        \li Generated output is used internally by the QML engine to avoid
            re-compilation, and to speed up execution. Direct Mode and Static
            Mode can further accelerate your application.
    \row
        \li Available for all versions of Qt
        \li Available for all versions of Qt
        \li Available for commercial customers
\endtable
*/
