qmltc: Don't re-check headers for their suffix
qmltyperegistrar already does that and warns about suspicious headers. Allowing only ".h" is overly restrictive. Since qmltc uses the .h suffix also to mark scopes it has pre-processed, we need to drop the preprocessing and determine the path names on the fly when writing the includes. Pick-to: 6.8 Fixes: QTBUG-125959 Change-Id: If68431ca92fd6625ca77beb6b00a460c43c987e5 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
265ae27a3c
commit
0f15921006
|
@ -24,6 +24,7 @@ set(cpp_sources
|
||||||
cpptypes/typewithsignal.h
|
cpptypes/typewithsignal.h
|
||||||
cpptypes/custominitialization.h
|
cpptypes/custominitialization.h
|
||||||
cpptypes/typewithrequiredproperties.h
|
cpptypes/typewithrequiredproperties.h
|
||||||
|
cpptypes/hpp.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(qml_sources
|
set(qml_sources
|
||||||
|
@ -137,6 +138,8 @@ set(qml_sources
|
||||||
badFile.qml
|
badFile.qml
|
||||||
|
|
||||||
requiredProperties.qml
|
requiredProperties.qml
|
||||||
|
|
||||||
|
hpp.qml
|
||||||
)
|
)
|
||||||
|
|
||||||
set(js_sources
|
set(js_sources
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
|
#ifndef HPP_HPP
|
||||||
|
#define HPP_HPP
|
||||||
|
|
||||||
|
#include <QtQml/qqml.h>
|
||||||
|
|
||||||
|
class Hpp : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
QML_ELEMENT
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // HPP_HPP
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright (C) 2024 The Qt Company Ltd.
|
||||||
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
|
||||||
|
|
||||||
|
import QmltcTests 1.0
|
||||||
|
|
||||||
|
Hpp {
|
||||||
|
objectName: "hpp"
|
||||||
|
}
|
|
@ -92,6 +92,8 @@
|
||||||
#include "signalconnections.h"
|
#include "signalconnections.h"
|
||||||
#include "requiredproperties.h"
|
#include "requiredproperties.h"
|
||||||
|
|
||||||
|
#include "hpp.h"
|
||||||
|
|
||||||
// Qt:
|
// Qt:
|
||||||
#include <QtCore/qstring.h>
|
#include <QtCore/qstring.h>
|
||||||
#include <QtCore/qbytearray.h>
|
#include <QtCore/qbytearray.h>
|
||||||
|
@ -3396,4 +3398,11 @@ void tst_qmltc::signalConnections()
|
||||||
QCOMPARE(createdByQmltc.objectName(), QLatin1String("second"));
|
QCOMPARE(createdByQmltc.objectName(), QLatin1String("second"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_qmltc::hpp()
|
||||||
|
{
|
||||||
|
QQmlEngine e;
|
||||||
|
PREPEND_NAMESPACE(hpp) createdByQmltc(&e);
|
||||||
|
QCOMPARE(createdByQmltc.objectName(), QLatin1String("hpp"));
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_qmltc)
|
QTEST_MAIN(tst_qmltc)
|
||||||
|
|
|
@ -105,4 +105,6 @@ private slots:
|
||||||
#endif
|
#endif
|
||||||
void urlToString();
|
void urlToString();
|
||||||
void signalConnections();
|
void signalConnections();
|
||||||
|
|
||||||
|
void hpp();
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,7 +89,7 @@ void QmltcVisitor::findCppIncludes()
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
const auto addCppInclude = [this](const QQmlJSScope::ConstPtr &type) {
|
const auto addCppInclude = [this](const QQmlJSScope::ConstPtr &type) {
|
||||||
if (QString includeFile = type->filePath(); includeFile.endsWith(u".h"))
|
if (QString includeFile = filePath(type); !includeFile.isEmpty())
|
||||||
m_cppIncludes.insert(std::move(includeFile));
|
m_cppIncludes.insert(std::move(includeFile));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -151,8 +151,8 @@ void QmltcVisitor::findCppIncludes()
|
||||||
for (const QQmlJSMetaProperty &p : properties) {
|
for (const QQmlJSMetaProperty &p : properties) {
|
||||||
findInType(p.type());
|
findInType(p.type());
|
||||||
|
|
||||||
if (p.isPrivate() && t->filePath().endsWith(u".h")) {
|
if (p.isPrivate()) {
|
||||||
const QString ownersInclude = t->filePath();
|
const QString ownersInclude = filePath(t);
|
||||||
QString privateInclude = constructPrivateInclude(ownersInclude);
|
QString privateInclude = constructPrivateInclude(ownersInclude);
|
||||||
if (!privateInclude.isEmpty())
|
if (!privateInclude.isEmpty())
|
||||||
m_cppIncludes.insert(std::move(privateInclude));
|
m_cppIncludes.insert(std::move(privateInclude));
|
||||||
|
@ -174,7 +174,7 @@ void QmltcVisitor::findCppIncludes()
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove own include
|
// remove own include
|
||||||
m_cppIncludes.remove(m_exportedRootScope->filePath());
|
m_cppIncludes.remove(filePath(m_exportedRootScope));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addCleanQmlTypeName(QStringList *names, const QQmlJSScope::ConstPtr &scope)
|
static void addCleanQmlTypeName(QStringList *names, const QQmlJSScope::ConstPtr &scope)
|
||||||
|
@ -191,16 +191,9 @@ static void addCleanQmlTypeName(QStringList *names, const QQmlJSScope::ConstPtr
|
||||||
|
|
||||||
bool QmltcVisitor::visit(QQmlJS::AST::UiObjectDefinition *object)
|
bool QmltcVisitor::visit(QQmlJS::AST::UiObjectDefinition *object)
|
||||||
{
|
{
|
||||||
const bool processingRoot = !rootScopeIsValid();
|
|
||||||
|
|
||||||
if (!QQmlJSImportVisitor::visit(object))
|
if (!QQmlJSImportVisitor::visit(object))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (processingRoot || m_currentScope->isInlineComponent()) {
|
|
||||||
Q_ASSERT(rootScopeIsValid());
|
|
||||||
setRootFilePath();
|
|
||||||
}
|
|
||||||
|
|
||||||
// we're not interested in non-QML scopes
|
// we're not interested in non-QML scopes
|
||||||
if (m_currentScope->scopeType() != QQmlSA::ScopeType::QMLScope)
|
if (m_currentScope->scopeType() != QQmlSA::ScopeType::QMLScope)
|
||||||
return true;
|
return true;
|
||||||
|
@ -831,14 +824,14 @@ void QmltcVisitor::checkNamesAndTypes(const QQmlJSScope::ConstPtr &type)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \internal
|
/*! \internal
|
||||||
* Sets the file paths for the document and the inline components roots.
|
* Returns the file path for the C++ header of \a scope or the header created
|
||||||
|
* by qmltc for it and its inline components.
|
||||||
*/
|
*/
|
||||||
void QmltcVisitor::setRootFilePath()
|
QString QmltcVisitor::filePath(const QQmlJSScope::ConstPtr &scope) const
|
||||||
{
|
{
|
||||||
const QString filePath = m_currentScope->filePath();
|
const QString filePath = scope->filePath();
|
||||||
if (filePath.endsWith(u".h")) // assume the correct path is set
|
if (!filePath.endsWith(u".qml")) // assume the correct path is set
|
||||||
return;
|
return scope->filePath();
|
||||||
Q_ASSERT(filePath.endsWith(u".qml"_s));
|
|
||||||
|
|
||||||
const QString correctedFilePath = sourceDirectoryPath(filePath);
|
const QString correctedFilePath = sourceDirectoryPath(filePath);
|
||||||
const QStringList paths = m_importer->resourceFileMapper()->resourcePaths(
|
const QStringList paths = m_importer->resourceFileMapper()->resourcePaths(
|
||||||
|
@ -850,13 +843,13 @@ void QmltcVisitor::setRootFilePath()
|
||||||
qCDebug(lcQmltcCompiler,
|
qCDebug(lcQmltcCompiler,
|
||||||
"Failed to find a header file name for path %s. Paths checked:\n%s",
|
"Failed to find a header file name for path %s. Paths checked:\n%s",
|
||||||
correctedFilePath.toUtf8().constData(), matchedPaths.toUtf8().constData());
|
correctedFilePath.toUtf8().constData(), matchedPaths.toUtf8().constData());
|
||||||
return;
|
return QString();
|
||||||
}
|
}
|
||||||
// NB: get the file name to avoid prefixes
|
// NB: get the file name to avoid prefixes
|
||||||
m_currentScope->setFilePath(QFileInfo(*firstHeader).fileName());
|
return QFileInfo(*firstHeader).fileName();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString QmltcVisitor::sourceDirectoryPath(const QString &path)
|
QString QmltcVisitor::sourceDirectoryPath(const QString &path) const
|
||||||
{
|
{
|
||||||
auto result = QQmlJSUtils::sourceDirectoryPath(m_importer, path);
|
auto result = QQmlJSUtils::sourceDirectoryPath(m_importer, path);
|
||||||
if (const QString *srcDirPath = std::get_if<QString>(&result))
|
if (const QString *srcDirPath = std::get_if<QString>(&result))
|
||||||
|
|
|
@ -23,9 +23,9 @@ class QmltcVisitor : public QQmlJSImportVisitor
|
||||||
&qmlIrOrderedBindings);
|
&qmlIrOrderedBindings);
|
||||||
void setupAliases();
|
void setupAliases();
|
||||||
void checkNamesAndTypes(const QQmlJSScope::ConstPtr &type);
|
void checkNamesAndTypes(const QQmlJSScope::ConstPtr &type);
|
||||||
void setRootFilePath();
|
QString filePath(const QQmlJSScope::ConstPtr &scope) const;
|
||||||
|
|
||||||
QString sourceDirectoryPath(const QString &path);
|
QString sourceDirectoryPath(const QString &path) const;
|
||||||
|
|
||||||
using InlineComponentOrDocumentRootName = QQmlJSScope::InlineComponentOrDocumentRootName;
|
using InlineComponentOrDocumentRootName = QQmlJSScope::InlineComponentOrDocumentRootName;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue