QQmlJSScope: Decouple ContextualTypes
ContextualTypes are required in the import visitor logic, but they aren't actually used directly inside QQmlJSScope. Change-Id: I5cd49076687ef97c1077678c8dc757cde3b94c51 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> Reviewed-by: Semih Yavuz <semih.yavuz@qt.io>
This commit is contained in:
parent
4bf10f9f9c
commit
5461b90cda
|
@ -30,6 +30,7 @@ qt_internal_add_module(QmlCompilerPrivate
|
|||
qqmljsresourcefilemapper.cpp qqmljsresourcefilemapper_p.h
|
||||
qqmljsscope.cpp qqmljsscope_p.h
|
||||
qqmljsscopesbyid_p.h
|
||||
qqmljscontextualtypes_p.h
|
||||
qqmljsshadowcheck.cpp qqmljsshadowcheck_p.h
|
||||
qqmljsstoragegeneralizer.cpp qqmljsstoragegeneralizer_p.h
|
||||
qqmljstypedescriptionreader.cpp qqmljstypedescriptionreader_p.h
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (C) 2023 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QQMLJSCONTEXTUALTYPES_P_H
|
||||
#define QQMLJSCONTEXTUALTYPES_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#include <QtCore/qstring.h>
|
||||
#include <QtCore/qhash.h>
|
||||
#include <private/qqmljsscope_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
namespace QQmlJS {
|
||||
/*! \internal
|
||||
* Maps type names to types and the compile context of the types. The context can be
|
||||
* INTERNAL (for c++ and synthetic jsrootgen types) or QML (for qml types).
|
||||
*/
|
||||
struct ContextualTypes
|
||||
{
|
||||
enum CompileContext { INTERNAL, QML };
|
||||
|
||||
ContextualTypes(
|
||||
CompileContext context,
|
||||
const QHash<QString, ImportedScope<QQmlJSScope::ConstPtr>> types,
|
||||
const QQmlJSScope::ConstPtr &arrayType)
|
||||
: m_types(types)
|
||||
, m_context(context)
|
||||
, m_arrayType(arrayType)
|
||||
{}
|
||||
|
||||
CompileContext context() const { return m_context; }
|
||||
QQmlJSScope::ConstPtr arrayType() const { return m_arrayType; }
|
||||
|
||||
bool hasType(const QString &name) const { return m_types.contains(name); }
|
||||
ImportedScope<QQmlJSScope::ConstPtr> type(const QString &name) const { return m_types[name]; }
|
||||
void setType(const QString &name, const ImportedScope<QQmlJSScope::ConstPtr> &type)
|
||||
{
|
||||
m_types.insert(name, type);
|
||||
}
|
||||
void clearType(const QString &name)
|
||||
{
|
||||
m_types[name].scope = QQmlJSScope::ConstPtr();
|
||||
}
|
||||
|
||||
bool isNullType(const QString &name) const
|
||||
{
|
||||
const auto it = m_types.constFind(name);
|
||||
return it != m_types.constEnd() && it->scope.isNull();
|
||||
}
|
||||
|
||||
void addTypes(ContextualTypes &&types)
|
||||
{
|
||||
Q_ASSERT(types.m_context == m_context);
|
||||
m_types.insert(std::move(types.m_types));
|
||||
}
|
||||
|
||||
void addTypes(const ContextualTypes &types)
|
||||
{
|
||||
Q_ASSERT(types.m_context == m_context);
|
||||
m_types.insert(types.m_types);
|
||||
}
|
||||
|
||||
const QHash<QString, ImportedScope<QQmlJSScope::ConstPtr>> &types() const { return m_types; }
|
||||
|
||||
void clearTypes() { m_types.clear(); }
|
||||
|
||||
private:
|
||||
QHash<QString, ImportedScope<QQmlJSScope::ConstPtr>> m_types;
|
||||
CompileContext m_context;
|
||||
|
||||
// For resolving enums
|
||||
QQmlJSScope::ConstPtr m_intType;
|
||||
|
||||
// For resolving sequence types
|
||||
QQmlJSScope::ConstPtr m_arrayType;
|
||||
};
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QQMLJSCONTEXTUALTYPES_P_H
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <private/qtqmlcompilerexports_p.h>
|
||||
|
||||
#include "qqmljscontextualtypes_p.h"
|
||||
#include "qqmljsscope_p.h"
|
||||
#include "qqmljsresourcefilemapper_p.h"
|
||||
#include <QtQml/private/qqmldirparser_p.h>
|
||||
|
@ -29,7 +30,7 @@ class QQmlJSLogger;
|
|||
class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSImporter
|
||||
{
|
||||
public:
|
||||
using ImportedTypes = QQmlJSScope::ContextualTypes;
|
||||
using ImportedTypes = QQmlJS::ContextualTypes;
|
||||
|
||||
QQmlJSImporter(const QStringList &importPaths, QQmlJSResourceFileMapper *mapper,
|
||||
bool useOptionalImports = false);
|
||||
|
@ -92,7 +93,7 @@ private:
|
|||
{
|
||||
AvailableTypes(ImportedTypes builtins)
|
||||
: cppNames(std::move(builtins))
|
||||
, qmlNames(QQmlJSScope::ContextualTypes::QML, {}, cppNames.arrayType())
|
||||
, qmlNames(QQmlJS::ContextualTypes::QML, {}, cppNames.arrayType())
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ void QQmlJSImportVisitor::importBaseModules()
|
|||
// Pulling in the modules and neighboring qml files of the qmltypes we're trying to lint is not
|
||||
// something we need to do.
|
||||
if (!m_logger->fileName().endsWith(u".qmltypes"_s)) {
|
||||
QQmlJSScope::ContextualTypes fromDirectory =
|
||||
QQmlJS::ContextualTypes fromDirectory =
|
||||
m_importer->importDirectory(m_implicitImportDirectory);
|
||||
m_rootScopeImports.addTypes(std::move(fromDirectory));
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
//
|
||||
// We mean it.
|
||||
|
||||
#include <private/qqmljscontextualtypes_p.h>
|
||||
#include <private/qtqmlcompilerexports_p.h>
|
||||
|
||||
#include "qqmljsannotation_p.h"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// Copyright (C) 2019 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qqmljscontextualtypes_p.h"
|
||||
#include "qqmljsscope_p.h"
|
||||
#include "qqmljstypereader_p.h"
|
||||
#include "qqmljsimporter_p.h"
|
||||
|
@ -379,7 +380,7 @@ std::optional<QQmlJSScope::JavaScriptIdentifier> QQmlJSScope::JSIdentifier(const
|
|||
}
|
||||
|
||||
static QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr>
|
||||
qFindInlineComponents(QStringView typeName, const QQmlJSScope::ContextualTypes &contextualTypes)
|
||||
qFindInlineComponents(QStringView typeName, const QQmlJS::ContextualTypes &contextualTypes)
|
||||
{
|
||||
const int separatorIndex = typeName.lastIndexOf(u'.');
|
||||
// do not crash in typeName.sliced() when it starts or ends with an '.'.
|
||||
|
@ -424,7 +425,7 @@ qFindInlineComponents(QStringView typeName, const QQmlJSScope::ContextualTypes &
|
|||
* ("qmlFileName.IC" is correctly resolved from qmlFileName).
|
||||
*/
|
||||
QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr> QQmlJSScope::findType(
|
||||
const QString &name, const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QString &name, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes)
|
||||
{
|
||||
const auto useType = [&]() {
|
||||
|
@ -457,7 +458,7 @@ QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr> QQmlJSScope::findType(
|
|||
};
|
||||
|
||||
switch (contextualTypes.context()) {
|
||||
case ContextualTypes::INTERNAL: {
|
||||
case QQmlJS::ContextualTypes::INTERNAL: {
|
||||
if (const auto listType = findListType(u"QList<"_s, u">"_s);
|
||||
listType.scope && !listType.scope->isReferenceType()) {
|
||||
return listType;
|
||||
|
@ -487,7 +488,7 @@ QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr> QQmlJSScope::findType(
|
|||
|
||||
break;
|
||||
}
|
||||
case ContextualTypes::QML: {
|
||||
case QQmlJS::ContextualTypes::QML: {
|
||||
// look after inline components
|
||||
const auto inlineComponent = qFindInlineComponents(name, contextualTypes);
|
||||
if (inlineComponent.scope) {
|
||||
|
@ -505,7 +506,7 @@ QQmlJSScope::ImportedScope<QQmlJSScope::ConstPtr> QQmlJSScope::findType(
|
|||
}
|
||||
|
||||
QTypeRevision QQmlJSScope::resolveType(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &context,
|
||||
const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &context,
|
||||
QSet<QString> *usedTypes)
|
||||
{
|
||||
if (self->accessSemantics() == AccessSemantics::Sequence
|
||||
|
@ -593,7 +594,7 @@ QTypeRevision QQmlJSScope::resolveType(
|
|||
|
||||
void QQmlJSScope::updateChildScope(
|
||||
const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self,
|
||||
const QQmlJSScope::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
|
||||
const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
|
||||
{
|
||||
switch (childScope->scopeType()) {
|
||||
case QQmlSA::ScopeType::GroupedPropertyScope:
|
||||
|
@ -627,7 +628,7 @@ void QQmlJSScope::updateChildScope(
|
|||
template<typename Resolver, typename ChildScopeUpdater>
|
||||
static QTypeRevision resolveTypesInternal(
|
||||
Resolver resolve, ChildScopeUpdater update, const QQmlJSScope::Ptr &self,
|
||||
const QQmlJSScope::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
|
||||
const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
|
||||
{
|
||||
const QTypeRevision revision = resolve(self, contextualTypes, usedTypes);
|
||||
// NB: constness ensures no detach
|
||||
|
@ -641,11 +642,11 @@ static QTypeRevision resolveTypesInternal(
|
|||
}
|
||||
|
||||
QTypeRevision QQmlJSScope::resolveTypes(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes)
|
||||
{
|
||||
const auto resolveAll = [](const QQmlJSScope::Ptr &self,
|
||||
const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes) {
|
||||
resolveEnums(self, contextualTypes, usedTypes);
|
||||
resolveList(self, contextualTypes.arrayType());
|
||||
|
@ -655,7 +656,7 @@ QTypeRevision QQmlJSScope::resolveTypes(
|
|||
}
|
||||
|
||||
void QQmlJSScope::resolveNonEnumTypes(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes)
|
||||
{
|
||||
resolveTypesInternal(resolveType, updateChildScope, self, contextualTypes, usedTypes);
|
||||
|
@ -696,7 +697,7 @@ static QString flagStorage(const QString &underlyingType)
|
|||
does not have an enum called like the alias.
|
||||
*/
|
||||
void QQmlJSScope::resolveEnums(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes)
|
||||
{
|
||||
// temporary hash to avoid messing up m_enumerations while iterators are active on it
|
||||
|
@ -758,8 +759,8 @@ void QQmlJSScope::resolveList(const QQmlJSScope::Ptr &self, const QQmlJSScope::C
|
|||
|
||||
const QQmlJSImportedScope element = {self, QTypeRevision()};
|
||||
const QQmlJSImportedScope array = {arrayType, QTypeRevision()};
|
||||
QQmlJSScope::ContextualTypes contextualTypes(
|
||||
QQmlJSScope::ContextualTypes::INTERNAL, { { self->internalName(), element }, },
|
||||
QQmlJS::ContextualTypes contextualTypes(
|
||||
QQmlJS::ContextualTypes::INTERNAL, { { self->internalName(), element }, },
|
||||
arrayType);
|
||||
QQmlJSScope::resolveTypes(listType, contextualTypes);
|
||||
|
||||
|
@ -769,7 +770,7 @@ void QQmlJSScope::resolveList(const QQmlJSScope::Ptr &self, const QQmlJSScope::C
|
|||
|
||||
void QQmlJSScope::resolveGeneralizedGroup(
|
||||
const Ptr &self, const ConstPtr &baseType,
|
||||
const QQmlJSScope::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
|
||||
const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes)
|
||||
{
|
||||
Q_ASSERT(baseType);
|
||||
// Generalized group properties are always composite,
|
||||
|
|
|
@ -157,6 +157,8 @@ struct ImportedScope {
|
|||
QTypeRevision revision;
|
||||
};
|
||||
|
||||
struct ContextualTypes;
|
||||
|
||||
} // namespace QQmlJS
|
||||
|
||||
class Q_QMLCOMPILER_PRIVATE_EXPORT QQmlJSScope
|
||||
|
@ -208,70 +210,6 @@ public:
|
|||
template <typename Pointer>
|
||||
using ExportedScope = QQmlJS::ExportedScope<Pointer>;
|
||||
|
||||
/*! \internal
|
||||
* Maps type names to types and the compile context of the types. The context can be
|
||||
* INTERNAl (for c++ and synthetic jsrootgen types) or QML (for qml types).
|
||||
*/
|
||||
struct ContextualTypes
|
||||
{
|
||||
enum CompileContext { INTERNAL, QML };
|
||||
|
||||
ContextualTypes(
|
||||
CompileContext context,
|
||||
const QHash<QString, ImportedScope<ConstPtr>> types,
|
||||
const QQmlJSScope::ConstPtr &arrayType)
|
||||
: m_types(types)
|
||||
, m_context(context)
|
||||
, m_arrayType(arrayType)
|
||||
{}
|
||||
|
||||
CompileContext context() const { return m_context; }
|
||||
ConstPtr arrayType() const { return m_arrayType; }
|
||||
|
||||
bool hasType(const QString &name) const { return m_types.contains(name); }
|
||||
ImportedScope<ConstPtr> type(const QString &name) const { return m_types[name]; }
|
||||
void setType(const QString &name, const ImportedScope<ConstPtr> &type)
|
||||
{
|
||||
m_types.insert(name, type);
|
||||
}
|
||||
void clearType(const QString &name)
|
||||
{
|
||||
m_types[name].scope = QQmlJSScope::ConstPtr();
|
||||
}
|
||||
|
||||
bool isNullType(const QString &name) const
|
||||
{
|
||||
const auto it = m_types.constFind(name);
|
||||
return it != m_types.constEnd() && it->scope.isNull();
|
||||
}
|
||||
|
||||
void addTypes(ContextualTypes &&types)
|
||||
{
|
||||
Q_ASSERT(types.m_context == m_context);
|
||||
m_types.insert(std::move(types.m_types));
|
||||
}
|
||||
|
||||
void addTypes(const ContextualTypes &types)
|
||||
{
|
||||
Q_ASSERT(types.m_context == m_context);
|
||||
m_types.insert(types.m_types);
|
||||
}
|
||||
|
||||
const QHash<QString, ImportedScope<ConstPtr>> &types() const { return m_types; }
|
||||
|
||||
void clearTypes() { m_types.clear(); }
|
||||
|
||||
private:
|
||||
QHash<QString, ImportedScope<ConstPtr>> m_types;
|
||||
CompileContext m_context;
|
||||
|
||||
// For resolving enums
|
||||
QQmlJSScope::ConstPtr m_intType;
|
||||
|
||||
// For resolving sequence types
|
||||
QQmlJSScope::ConstPtr m_arrayType;
|
||||
};
|
||||
|
||||
struct JavaScriptIdentifier
|
||||
{
|
||||
enum Kind {
|
||||
|
@ -516,19 +454,19 @@ public:
|
|||
QVector<QQmlJSScope::ConstPtr> childScopes() const;
|
||||
|
||||
static QTypeRevision resolveTypes(
|
||||
const Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes = nullptr);
|
||||
static void resolveNonEnumTypes(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes = nullptr);
|
||||
static void resolveEnums(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes = nullptr);
|
||||
static void resolveList(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &arrayType);
|
||||
static void resolveGeneralizedGroup(
|
||||
const QQmlJSScope::Ptr &self, const QQmlJSScope::ConstPtr &baseType,
|
||||
const QQmlJSScope::ContextualTypes &contextualTypes,
|
||||
const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes = nullptr);
|
||||
|
||||
void setSourceLocation(const QQmlJS::SourceLocation &sourceLocation);
|
||||
|
@ -562,7 +500,7 @@ public:
|
|||
};
|
||||
|
||||
static ImportedScope<QQmlJSScope::ConstPtr> findType(const QString &name,
|
||||
const ContextualTypes &contextualTypes,
|
||||
const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes = nullptr);
|
||||
|
||||
static QQmlSA::Element createQQmlSAElement(const ConstPtr &);
|
||||
|
@ -575,11 +513,11 @@ private:
|
|||
QQmlJSScope(const QQmlJSScope &) = default;
|
||||
QQmlJSScope &operator=(const QQmlJSScope &) = default;
|
||||
static QTypeRevision resolveType(
|
||||
const QQmlJSScope::Ptr &self, const ContextualTypes &contextualTypes,
|
||||
const QQmlJSScope::Ptr &self, const QQmlJS::ContextualTypes &contextualTypes,
|
||||
QSet<QString> *usedTypes);
|
||||
static void updateChildScope(
|
||||
const QQmlJSScope::Ptr &childScope, const QQmlJSScope::Ptr &self,
|
||||
const QQmlJSScope::ContextualTypes &contextualTypes, QSet<QString> *usedTypes);
|
||||
const QQmlJS::ContextualTypes &contextualTypes, QSet<QString> *usedTypes);
|
||||
|
||||
void addOwnPropertyBindingInQmlIROrder(const QQmlJSMetaPropertyBinding &binding,
|
||||
BindingTargetSpecifier specifier);
|
||||
|
|
|
@ -208,7 +208,7 @@ void tst_qqmljsscope::allTypesAvailable()
|
|||
|
||||
QQmlJSImporter importer { importPaths, /* resource file mapper */ nullptr };
|
||||
const auto imported = importer.importModule(u"QtQml"_s);
|
||||
QCOMPARE(imported.context(), QQmlJSScope::ContextualTypes::QML);
|
||||
QCOMPARE(imported.context(), QQmlJS::ContextualTypes::QML);
|
||||
const auto types = imported.types();
|
||||
QVERIFY(types.contains(u"$internal$.QObject"_s));
|
||||
QVERIFY(types.contains(u"QtObject"_s));
|
||||
|
|
Loading…
Reference in New Issue