diff options
-rw-r--r-- | qmake/generators/metamakefile.cpp | 4 | ||||
-rw-r--r-- | src/corelib/global/qlibraryinfo.cpp | 4 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.cpp | 57 | ||||
-rw-r--r-- | src/corelib/io/qfileinfo.h | 19 | ||||
-rw-r--r-- | src/gui/itemmodels/qfileinfogatherer.cpp | 3 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbsessionmanager.cpp | 2 | ||||
-rw-r--r-- | src/testlib/qtestcase.cpp | 2 | ||||
-rw-r--r-- | src/tools/androiddeployqt/main.cpp | 5 | ||||
-rw-r--r-- | tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp | 2 | ||||
-rw-r--r-- | tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp | 2 |
10 files changed, 83 insertions, 17 deletions
diff --git a/qmake/generators/metamakefile.cpp b/qmake/generators/metamakefile.cpp index 8d1eb1d886..8ba941c213 100644 --- a/qmake/generators/metamakefile.cpp +++ b/qmake/generators/metamakefile.cpp @@ -335,11 +335,11 @@ SubdirsMetaMakefileGenerator::init() QFileInfo subdir(subdirs.at(i).toQString()); const ProKey fkey(subdirs.at(i) + ".file"); if (!project->isEmpty(fkey)) { - subdir = project->first(fkey).toQString(); + subdir = QFileInfo(project->first(fkey).toQString()); } else { const ProKey skey(subdirs.at(i) + ".subdir"); if (!project->isEmpty(skey)) - subdir = project->first(skey).toQString(); + subdir = QFileInfo(project->first(skey).toQString()); } QString sub_name; if(subdir.isDir()) diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp index 990c4269e3..4cd940a7a3 100644 --- a/src/corelib/global/qlibraryinfo.cpp +++ b/src/corelib/global/qlibraryinfo.cpp @@ -597,8 +597,8 @@ QString qmake_abslocation(); static QString getPrefixFromHostBinDir(const char *hostBinDirToPrefixPath) { - const QFileInfo qmfi = QFileInfo(qmake_abslocation()).canonicalFilePath(); - return QDir::cleanPath(qmfi.absolutePath() + QLatin1Char('/') + const QString canonicalQMakePath = QFileInfo(qmake_abslocation()).canonicalPath(); + return QDir::cleanPath(canonicalQMakePath + QLatin1Char('/') + QLatin1String(hostBinDirToPrefixPath)); } diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp index 8b80141a32..4b81467687 100644 --- a/src/corelib/io/qfileinfo.cpp +++ b/src/corelib/io/qfileinfo.cpp @@ -1621,5 +1621,62 @@ QDebug operator<<(QDebug dbg, const QFileInfo &fi) Returns symLinkTarget() as a \c{std::filesystem::path}. \sa symLinkTarget() */ +/*! + \macro QT_IMPLICIT_QFILEINFO_CONSTRUCTION + \since 6.0 + \relates QFileInfo + + Defining this macro makes most QFileInfo constructors implicit + instead of explicit. Since construction of QFileInfo objects is + expensive, one should avoid accidentally creating them, especially + if cheaper alternatives exist. For instance: + + \badcode + + QDirIterator it(dir); + while (it.hasNext()) { + // Implicit conversion from QString (returned by it.next()): + // may create unnecessary data strucutres and cause additional + // accesses to the file system. Unless this macro is defined, + // this line does not compile. + + QFileInfo fi = it.next(); + + ~~~ + } + + \endcode + + Instead, use the right API: + + \code + + QDirIterator it(dir); + while (it.hasNext()) { + it.next(); + + // Extract the QFileInfo from the iterator directly: + QFileInfo fi = it.fileInfo(); + + ~~~ + } + + \endcode + + Construction from QString, QFile, and so on is always possible by + using direct initialization instead of copy initialization: + + \code + + QFileInfo fi1 = some_string; // Does not compile unless this macro is defined + QFileInfo fi2(some_string); // OK + QFileInfo fi3{some_string}; // Possibly better, avoids the risk of the Most Vexing Parse + auto fi4 = QFileInfo(some_string); // OK + + \endcode + + This macro is provided for compatibility reason. Its usage is not + recommended in new code. +*/ QT_END_NAMESPACE diff --git a/src/corelib/io/qfileinfo.h b/src/corelib/io/qfileinfo.h index 344c16abf8..90be1c2540 100644 --- a/src/corelib/io/qfileinfo.h +++ b/src/corelib/io/qfileinfo.h @@ -59,23 +59,32 @@ class Q_CORE_EXPORT QFileInfo public: explicit QFileInfo(QFileInfoPrivate *d); +#ifdef QT_IMPLICIT_QFILEINFO_CONSTRUCTION +#define QFILEINFO_MAYBE_EXPLICIT Q_IMPLICIT +#else +#define QFILEINFO_MAYBE_EXPLICIT explicit +#endif + QFileInfo(); - QFileInfo(const QString &file); - QFileInfo(const QFileDevice &file); - QFileInfo(const QDir &dir, const QString &file); + QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QString &file); + QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QFileDevice &file); + QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QDir &dir, const QString &file); QFileInfo(const QFileInfo &fileinfo); #ifdef Q_CLANG_QDOC QFileInfo(const std::filesystem::path &file); QFileInfo(const QDir &dir, const std::filesystem::path &file); #elif QT_CONFIG(cxx17_filesystem) template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> - QFileInfo(const T &file) : QFileInfo(QtPrivate::fromFilesystemPath(file)) { } + QFILEINFO_MAYBE_EXPLICIT QFileInfo(const T &file) : QFileInfo(QtPrivate::fromFilesystemPath(file)) { } template<typename T, QtPrivate::ForceFilesystemPath<T> = 0> - QFileInfo(const QDir &dir, const T &file) : QFileInfo(dir, QtPrivate::fromFilesystemPath(file)) + QFILEINFO_MAYBE_EXPLICIT QFileInfo(const QDir &dir, const T &file) : QFileInfo(dir, QtPrivate::fromFilesystemPath(file)) { } #endif // QT_CONFIG(cxx17_filesystem) + +#undef QFILEINFO_MAYBE_EXPLICIT + ~QFileInfo(); QFileInfo &operator=(const QFileInfo &fileinfo); diff --git a/src/gui/itemmodels/qfileinfogatherer.cpp b/src/gui/itemmodels/qfileinfogatherer.cpp index 417c3d7e42..bd368e945c 100644 --- a/src/gui/itemmodels/qfileinfogatherer.cpp +++ b/src/gui/itemmodels/qfileinfogatherer.cpp @@ -350,8 +350,7 @@ QExtendedInformation QFileInfoGatherer::getInfo(const QFileInfo &fileInfo) const #ifdef Q_OS_WIN if (m_resolveSymlinks && info.isSymLink(/* ignoreNtfsSymLinks = */ true)) { - QFileInfo resolvedInfo(fileInfo.symLinkTarget()); - resolvedInfo = resolvedInfo.canonicalFilePath(); + QFileInfo resolvedInfo(QFileInfo(fileInfo.symLinkTarget()).canonicalFilePath()); if (resolvedInfo.exists()) { emit nameResolved(fileInfo.filePath(), resolvedInfo.fileName()); } diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp index e9697f505b..002fccba07 100644 --- a/src/plugins/platforms/xcb/qxcbsessionmanager.cpp +++ b/src/plugins/platforms/xcb/qxcbsessionmanager.cpp @@ -230,7 +230,7 @@ static void sm_performSaveYourself(QXcbSessionManager *sm) restart << argument0 << QLatin1String("-session") << sm->sessionId() + QLatin1Char('_') + sm->sessionKey(); - QFileInfo fi = QCoreApplication::applicationFilePath(); + QFileInfo fi(QCoreApplication::applicationFilePath()); if (qAppName().compare(fi.fileName(), Qt::CaseInsensitive) != 0) restart << QLatin1String("-name") << qAppName(); sm->setRestartCommand(restart); diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 992149ff20..7bca8de1b6 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2211,7 +2211,7 @@ QString QTest::qFindTestData(const QString& base, const char *file, int line, co // 3. relative to test source. if (found.isEmpty() && qstrncmp(file, ":/", 2) != 0) { // srcdir is the directory containing the calling source file. - QFileInfo srcdir = QFileInfo(QFile::decodeName(file)).path(); + QFileInfo srcdir(QFileInfo(QFile::decodeName(file)).path()); // If the srcdir is relative, that means it is relative to the current working // directory of the compiler at compile time, which should be passed in as `builddir'. diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 0e04f97a33..1b29fe7381 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -1561,8 +1561,9 @@ QList<QtDependency> findFilesRecursively(const Options &options, const QFileInfo const QStringList entries = dir.entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot); for (const QString &entry : entries) { - QString s = info.absoluteFilePath() + QLatin1Char('/') + entry; - ret += findFilesRecursively(options, s, rootPath); + ret += findFilesRecursively(options, + QFileInfo(info.absoluteFilePath() + QChar(u'/') + entry), + rootPath); } return ret; diff --git a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp index b0b076310d..2d7c1b295a 100644 --- a/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp +++ b/tests/auto/corelib/io/qstandardpaths/tst_qstandardpaths.cpp @@ -364,7 +364,7 @@ static inline QFileInfo findSh() const QStringList rawPaths = QString::fromLocal8Bit(pEnv.constData()).split(pathSep, Qt::SkipEmptyParts); foreach (const QString &path, rawPaths) { if (QFile::exists(path + sh)) - return path + sh; + return QFileInfo(path + sh); } return QFileInfo(); } diff --git a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp index 4824973576..9e9625854e 100644 --- a/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp +++ b/tests/auto/widgets/itemviews/qfileiconprovider/tst_qfileiconprovider.cpp @@ -126,7 +126,7 @@ void tst_QFileIconProvider::type() static QIcon getIcon() { QFileIconProvider fip; - return fip.icon(QDir::currentPath()); + return fip.icon(QFileInfo(QDir::currentPath())); } void tst_QFileIconProvider::taskQTBUG_46755_QFileIconEngine_crash() |