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::InstructionAnnotations QQmlJSStorageGeneralizer::run(
23 InstructionAnnotations annotations, Function *function,
24 QQmlJS::DiagnosticMessage *error)
25{
26 m_error = error;
27
28 if (QQmlJSScope::ConstPtr &returnType = function->returnType) {
29 if (QQmlJSScope::ConstPtr stored = m_typeResolver->genericType(
30 type: returnType, allowComponent: QQmlJSTypeResolver::ComponentIsGeneric::Yes)) {
31 returnType = stored;
32 } else {
33 setError(QStringLiteral("Cannot store the return type %1.")
34 .arg(a: returnType->internalName(), fieldWidth: 0));
35 return InstructionAnnotations();
36 }
37 }
38
39 const auto transformRegister = [&](QQmlJSRegisterContent &content) {
40 if (const QQmlJSScope::ConstPtr &specific = content.storedType())
41 m_typeResolver->generalizeType(type: specific);
42 };
43
44 const auto transformRegisters = [&](VirtualRegisters &registers) {
45 for (auto j = registers.begin(), jEnd = registers.end(); j != jEnd; ++j) {
46 QQmlJSRegisterContent &content = j.value().content;
47 transformRegister(content);
48 }
49 };
50
51 for (QQmlJSRegisterContent &argument : function->argumentTypes) {
52 Q_ASSERT(argument.isValid());
53 transformRegister(argument);
54 }
55
56 for (auto i = annotations.begin(), iEnd = annotations.end(); i != iEnd; ++i) {
57 transformRegister(i->second.changedRegister);
58 transformRegisters(i->second.typeConversions);
59 }
60
61 return annotations;
62}
63
64QT_END_NAMESPACE
65

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