1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "qqmljsstoragegeneralizer_p.h"
5
6QT_BEGIN_NAMESPACE
7
8/*!
9 * \internal
10 * \class QQmlJSStorageGeneralizer
11 *
12 * The QQmlJSStorageGeneralizer is a compile pass that changes all type
13 * annotations and the function signature to use a generic storage type like
14 * QVariant or QObject*. This is necessary if we cannot rely on the original
15 * type to be immediately accessible, for example because we cannot include its
16 * header.
17 *
18 * QQmlJSStorageGeneralizer does not have to use the byte code at all but
19 * operates only on the annotations and the function description.
20 */
21
22QQmlJSCompilePass::BlocksAndAnnotations
23QQmlJSStorageGeneralizer::run(Function *function, QQmlJS::DiagnosticMessage *error)
24{
25 m_error = error;
26
27 if (QQmlJSRegisterContent &returnType = function->returnType; returnType.isValid()) {
28 if (QQmlJSScope::ConstPtr stored = m_typeResolver->genericType(
29 type: returnType.storedType(), allowComponent: QQmlJSTypeResolver::ComponentIsGeneric::Yes)) {
30 returnType = returnType.storedIn(newStoredType: stored);
31 } else {
32 setError(QStringLiteral("Cannot store the return type %1.")
33 .arg(a: returnType.storedType()->internalName()));
34 return {};
35 }
36 }
37
38 const auto transformRegister = [&](QQmlJSRegisterContent &content) {
39 if (const QQmlJSScope::ConstPtr &specific = content.storedType())
40 m_typeResolver->generalizeType(type: specific);
41 };
42
43 const auto transformRegisters = [&](VirtualRegisters &registers) {
44 for (auto j = registers.begin(), jEnd = registers.end(); j != jEnd; ++j) {
45 QQmlJSRegisterContent &content = j.value().content;
46 transformRegister(content);
47 }
48 };
49
50 for (QQmlJSRegisterContent &argument : function->argumentTypes) {
51 Q_ASSERT(argument.isValid());
52 transformRegister(argument);
53 }
54
55 for (auto i = m_annotations.begin(), iEnd = m_annotations.end(); i != iEnd; ++i) {
56 transformRegister(i->second.changedRegister);
57 transformRegisters(i->second.typeConversions);
58 }
59
60 return { .basicBlocks: std::move(m_basicBlocks), .annotations: std::move(m_annotations) };
61}
62
63QT_END_NAMESPACE
64

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

source code of qtdeclarative/src/qmlcompiler/qqmljsstoragegeneralizer.cpp