aboutsummaryrefslogtreecommitdiffstats
path: root/src/qmlcompiler/qqmljsscope_p.h
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2021-12-17 14:23:55 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-01-21 14:23:08 +0100
commitcb4e0c119607a48e1f5e0cea9273afd914c15b25 (patch)
tree4717b75e129bc26bbb1b792092038a6c223617ae /src/qmlcompiler/qqmljsscope_p.h
parentdab5656d38a3d53c2d81b20e9bb8bc162edf7716 (diff)
QmlCompiler: Respect revisions
The only place where revisions matter is at the boundary between composite and non-composite types. The revision of the first composite type inherited from determines which members of all composite ancestors are available. Therefore, store the revision together with the base type and pass it through the imports to have it available. Then use it to check availability of methods and properties. The test exposes two further problems, which are fixed, too: 1. If no method is found to call, we need to generate an error in the type propagator. We don't know what the call will result in, after all, and the code generator should reject it. 2. We need to check the right scopes for hasOwnMethod(). Otherwise we might not find methods that are available. Fixes: QTBUG-99128 Change-Id: I4c320b8dfb490b140d7b8c16e6b638b32f156faa Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit e19d48d07310708e56cb379124dff193c1a7fa71)
Diffstat (limited to 'src/qmlcompiler/qqmljsscope_p.h')
-rw-r--r--src/qmlcompiler/qqmljsscope_p.h86
1 files changed, 57 insertions, 29 deletions
diff --git a/src/qmlcompiler/qqmljsscope_p.h b/src/qmlcompiler/qqmljsscope_p.h
index 7728407a0d..be278a6c7b 100644
--- a/src/qmlcompiler/qqmljsscope_p.h
+++ b/src/qmlcompiler/qqmljsscope_p.h
@@ -136,20 +136,36 @@ public:
class Export {
public:
Export() = default;
- Export(QString package, QString type, const QTypeRevision &version);
+ Export(QString package, QString type, QTypeRevision version, QTypeRevision revision);
bool isValid() const;
QString package() const { return m_package; }
QString type() const { return m_type; }
QTypeRevision version() const { return m_version; }
+ QTypeRevision revision() const { return m_revision; }
private:
QString m_package;
QString m_type;
QTypeRevision m_version;
+ QTypeRevision m_revision;
};
+ template<typename Pointer>
+ struct ExportedScope {
+ Pointer scope;
+ QList<QQmlJSScope::Export> exports;
+ };
+
+ template<typename Pointer>
+ struct ImportedScope {
+ Pointer scope;
+ QTypeRevision revision;
+ };
+
+ using ContextualTypes = QHash<QString, ImportedScope<ConstPtr>>;
+
struct JavaScriptIdentifier
{
enum Kind {
@@ -242,8 +258,9 @@ public:
// relevant base class (in the hierarchy starting from QObject) of a C++ type.
void setBaseTypeName(const QString &baseTypeName) { m_baseTypeName = baseTypeName; }
QString baseTypeName() const { return m_baseTypeName; }
- QQmlJSScope::ConstPtr baseType() const { return m_baseType; }
- void clearBaseType() { m_baseType = QQmlJSScope::WeakConstPtr(); }
+ QQmlJSScope::ConstPtr baseType() const { return m_baseType.scope; }
+ QTypeRevision baseTypeRevision() const { return m_baseType.revision; }
+ void clearBaseType() { m_baseType = {}; }
void addOwnProperty(const QQmlJSMetaProperty &prop) { m_properties.insert(prop.propertyName(), prop); }
QHash<QString, QQmlJSMetaProperty> ownProperties() const { return m_properties; }
@@ -360,18 +377,18 @@ public:
return result;
}
- static void resolveTypes(const QQmlJSScope::Ptr &self,
- const QHash<QString, ConstPtr> &contextualTypes,
- QSet<QString> *usedTypes = nullptr);
- static void resolveNonEnumTypes(const QQmlJSScope::Ptr &self,
- const QHash<QString, ConstPtr> &contextualTypes,
- QSet<QString> *usedTypes = nullptr);
- static void resolveEnums(const QQmlJSScope::Ptr &self,
- const QQmlJSScope::ConstPtr &intType);
- static void resolveGeneralizedGroup(const QQmlJSScope::Ptr &self,
- const QQmlJSScope::ConstPtr &baseType,
- const QHash<QString, ConstPtr> &contextualTypes,
- QSet<QString> *usedTypes = nullptr);
+ static QTypeRevision resolveTypes(
+ const Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
+ QSet<QString> *usedTypes = nullptr);
+ static void resolveNonEnumTypes(
+ const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
+ QSet<QString> *usedTypes = nullptr);
+ static void resolveEnums(
+ const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &intType);
+ static void resolveGeneralizedGroup(
+ const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &baseType,
+ const QQmlJSScope::ContextualTypes &contextualTypes,
+ QSet<QString> *usedTypes = nullptr);
void setSourceLocation(const QQmlJS::SourceLocation &sourceLocation)
{
@@ -392,6 +409,16 @@ public:
return {};
}
+ static QTypeRevision nonCompositeBaseRevision(const ImportedScope<QQmlJSScope::ConstPtr> &scope)
+ {
+ for (auto base = scope; base.scope;
+ base = { base.scope->m_baseType.scope, base.scope->m_baseType.revision }) {
+ if (!base.scope->isComposite())
+ return base.revision;
+ }
+ return {};
+ }
+
/*!
\internal
Checks whether \a otherScope is the same type as this.
@@ -435,15 +462,15 @@ public:
private:
QQmlJSScope(ScopeType type, const QQmlJSScope::Ptr &parentScope = QQmlJSScope::Ptr());
- static QQmlJSScope::ConstPtr
- findType(const QString &name, const QHash<QString, QQmlJSScope::ConstPtr> &contextualTypes,
- QSet<QString> *usedTypes = nullptr);
- static void resolveType(const QQmlJSScope::Ptr &self,
- const QHash<QString, ConstPtr> &contextualTypes,
- QSet<QString> *usedTypes);
- static void updateChildScope(const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self,
- const QHash<QString, QQmlJSScope::ConstPtr> &contextualTypes,
- QSet<QString> *usedTypes);
+ static ImportedScope<QQmlJSScope::ConstPtr> findType(
+ const QString &name, const ContextualTypes &contextualTypes,
+ QSet<QString> *usedTypes = nullptr);
+ static QTypeRevision resolveType(
+ const QQmlJSScope::Ptr &self, const ContextualTypes &contextualTypes,
+ QSet<QString> *usedTypes);
+ static void updateChildScope(
+ const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self,
+ const QQmlJSScope::ContextualTypes &contextualTypes, QSet<QString> *usedTypes);
QHash<QString, JavaScriptIdentifier> m_jsIdentifiers;
@@ -459,7 +486,10 @@ private:
QString m_fileName;
QString m_internalName;
QString m_baseTypeName;
- QQmlJSScope::WeakConstPtr m_baseType;
+
+ // We only need the revision for the base type as inheritance is
+ // the only relation between two types where the revisions matter.
+ ImportedScope<QQmlJSScope::WeakConstPtr> m_baseType;
ScopeType m_scopeType = QMLScope;
QStringList m_interfaceNames;
@@ -518,10 +548,8 @@ private:
bool m_isSingleton = false;
};
-struct QQmlJSExportedScope {
- QQmlJSScope::Ptr scope;
- QList<QQmlJSScope::Export> exports;
-};
+using QQmlJSExportedScope = QQmlJSScope::ExportedScope<QQmlJSScope::Ptr>;
+using QQmlJSImportedScope = QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr>;
struct QQmlJSTypeInfo
{