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 | |
6 | QT_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 | |
22 | QQmlJSCompilePass::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 ®isters) { |
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 | |
64 | QT_END_NAMESPACE |
65 |