aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/qmlcompiler/qqmljslinter.cpp1
-rw-r--r--src/qmlcompiler/qqmljslogger.cpp60
-rw-r--r--src/qmlcompiler/qqmljslogger_p.h18
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp13
4 files changed, 68 insertions, 24 deletions
diff --git a/src/qmlcompiler/qqmljslinter.cpp b/src/qmlcompiler/qqmljslinter.cpp
index 91182e8f60..4d3eb8e9b5 100644
--- a/src/qmlcompiler/qqmljslinter.cpp
+++ b/src/qmlcompiler/qqmljslinter.cpp
@@ -221,6 +221,7 @@ bool QQmlJSLinter::lintFile(const QString &filename, const QString *fileContents
jsonFix[u"charOffset"_qs] = static_cast<int>(fix.cutLocation.offset);
jsonFix[u"length"_qs] = static_cast<int>(fix.cutLocation.length);
jsonFix[u"replacement"_qs] = fix.replacementString;
+ jsonFix[u"isHint"] = fix.isHint;
suggestions << jsonFix;
}
}
diff --git a/src/qmlcompiler/qqmljslogger.cpp b/src/qmlcompiler/qqmljslogger.cpp
index cba6a24d60..ce2f559c1a 100644
--- a/src/qmlcompiler/qqmljslogger.cpp
+++ b/src/qmlcompiler/qqmljslogger.cpp
@@ -28,6 +28,9 @@
#include "qqmljslogger_p.h"
+#include <QtCore/qfile.h>
+#include <QtCore/qfileinfo.h>
+
QT_BEGIN_NAMESPACE
const QMap<QString, QQmlJSLogger::Option> &QQmlJSLogger::options() {
@@ -133,7 +136,8 @@ static bool isMsgTypeLess(QtMsgType a, QtMsgType b)
void QQmlJSLogger::log(const QString &message, QQmlJSLoggerCategory category,
const QQmlJS::SourceLocation &srcLocation, QtMsgType type, bool showContext,
- bool showFileName, const std::optional<FixSuggestion> &suggestion)
+ bool showFileName, const std::optional<FixSuggestion> &suggestion,
+ const QString overrideFileName)
{
if (isCategoryIgnored(category))
return;
@@ -145,8 +149,9 @@ void QQmlJSLogger::log(const QString &message, QQmlJSLoggerCategory category,
QString prefix;
- if (!m_fileName.isEmpty() && showFileName)
- prefix = m_fileName + QStringLiteral(":");
+ if ((!overrideFileName.isEmpty() || !m_fileName.isEmpty()) && showFileName)
+ prefix =
+ (!overrideFileName.isEmpty() ? overrideFileName : m_fileName) + QStringLiteral(":");
if (srcLocation.isValid())
prefix += QStringLiteral("%1:%2:").arg(srcLocation.startLine).arg(srcLocation.startColumn);
@@ -176,7 +181,7 @@ void QQmlJSLogger::log(const QString &message, QQmlJSLoggerCategory category,
}
if (srcLocation.isValid() && !m_code.isEmpty() && showContext)
- printContext(srcLocation);
+ printContext(overrideFileName, srcLocation);
if (suggestion.has_value())
printFix(suggestion.value());
@@ -198,9 +203,19 @@ void QQmlJSLogger::processMessages(const QList<QQmlJS::DiagnosticMessage> &messa
m_output.write(QStringLiteral("---\n\n"));
}
-void QQmlJSLogger::printContext(const QQmlJS::SourceLocation &location)
+void QQmlJSLogger::printContext(const QString &overrideFileName,
+ const QQmlJS::SourceLocation &location)
{
- IssueLocationWithContext issueLocationWithContext { m_code, location };
+ QString code = m_code;
+
+ if (!overrideFileName.isEmpty() && overrideFileName != QFileInfo(m_fileName).absolutePath()) {
+ QFile file(overrideFileName);
+ const bool success = file.open(QFile::ReadOnly);
+ Q_ASSERT(success);
+ code = QString::fromUtf8(file.readAll());
+ }
+
+ IssueLocationWithContext issueLocationWithContext { code, location };
if (const QStringView beforeText = issueLocationWithContext.beforeText(); !beforeText.isEmpty())
m_output.write(beforeText);
@@ -224,33 +239,56 @@ void QQmlJSLogger::printContext(const QQmlJS::SourceLocation &location)
void QQmlJSLogger::printFix(const FixSuggestion &fix)
{
+ const QString currentFileAbsPath = QFileInfo(m_fileName).absolutePath();
+ QString code = m_code;
+ QString currentFile;
for (const auto &fixItem : fix.fixes) {
m_output.writePrefixedMessage(fixItem.message, QtInfoMsg);
if (!fixItem.cutLocation.isValid())
continue;
- IssueLocationWithContext issueLocationWithContext { m_code, fixItem.cutLocation };
+ if (fixItem.fileName == currentFile) {
+ // Nothing to do in this case, we've already read the code
+ } else if (fixItem.fileName.isEmpty() || fixItem.fileName == currentFileAbsPath) {
+ code = m_code;
+ } else {
+ QFile file(fixItem.fileName);
+ const bool success = file.open(QFile::ReadOnly);
+ Q_ASSERT(success);
+ code = QString::fromUtf8(file.readAll());
+ currentFile = fixItem.fileName;
+ }
+
+ IssueLocationWithContext issueLocationWithContext { code, fixItem.cutLocation };
if (const QStringView beforeText = issueLocationWithContext.beforeText();
!beforeText.isEmpty()) {
m_output.write(beforeText);
}
- m_output.write(fixItem.replacementString, QtDebugMsg);
+ // The replacement string can be empty if we're only pointing something out to the user
+ QStringView replacementString = fixItem.replacementString.isEmpty()
+ ? issueLocationWithContext.issueText()
+ : fixItem.replacementString;
+
+ // But if there's nothing to change it has to be a hint
+ if (fixItem.replacementString.isEmpty())
+ Q_ASSERT(fixItem.isHint);
+
+ m_output.write(replacementString, QtDebugMsg);
m_output.write(issueLocationWithContext.afterText().toString() + u'\n');
int tabCount = issueLocationWithContext.beforeText().count(u'\t');
// Do not draw location indicator for multiline replacement strings
- if (fixItem.replacementString.contains(u'\n'))
+ if (replacementString.contains(u'\n'))
continue;
m_output.write(u" "_qs.repeated(
issueLocationWithContext.beforeText().length() - tabCount)
+ u"\t"_qs.repeated(tabCount)
- + u"^"_qs.repeated(fixItem.replacementString.length())
- + u'\n');
+ + u"^"_qs.repeated(fixItem.replacementString.length()) + u'\n');
}
}
diff --git a/src/qmlcompiler/qqmljslogger_p.h b/src/qmlcompiler/qqmljslogger_p.h
index 462854225f..2ddcb2ac5a 100644
--- a/src/qmlcompiler/qqmljslogger_p.h
+++ b/src/qmlcompiler/qqmljslogger_p.h
@@ -122,6 +122,10 @@ struct FixSuggestion
QString message;
QQmlJS::SourceLocation cutLocation = QQmlJS::SourceLocation();
QString replacementString = QString();
+ QString fileName = QString();
+ // A Fix is a hint if it can not be automatically applied to fix an issue or only points out
+ // its origin
+ bool isHint = true;
};
QList<Fix> fixes;
};
@@ -233,10 +237,11 @@ public:
*/
void log(const QString &message, QQmlJSLoggerCategory category,
const QQmlJS::SourceLocation &srcLocation, bool showContext = true,
- bool showFileName = true, const std::optional<FixSuggestion> &suggestion = {})
+ bool showFileName = true, const std::optional<FixSuggestion> &suggestion = {},
+ const QString overrideFileName = QString())
{
log(message, category, srcLocation, m_categoryLevels[category], showContext, showFileName,
- suggestion);
+ suggestion, overrideFileName);
}
void processMessages(const QList<QQmlJS::DiagnosticMessage> &messages,
@@ -257,12 +262,13 @@ public:
QString fileName() const { return m_fileName; }
private:
- void printContext(const QQmlJS::SourceLocation &location);
+ void printContext(const QString &overrideFileName, const QQmlJS::SourceLocation &location);
void printFix(const FixSuggestion &fix);
- void log(const QString &message, QQmlJSLoggerCategory category, const QQmlJS::SourceLocation &,
- QtMsgType type, bool showContext, bool showFileName,
- const std::optional<FixSuggestion> &suggestion);
+ void log(const QString &message, QQmlJSLoggerCategory category,
+ const QQmlJS::SourceLocation &srcLocation, QtMsgType type, bool showContext,
+ bool showFileName, const std::optional<FixSuggestion> &suggestion,
+ const QString overrideFileName);
QString m_fileName;
QString m_code;
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp
index 52dd8df72f..fb7c40cf7a 100644
--- a/src/qmlcompiler/qqmljstypepropagator.cpp
+++ b/src/qmlcompiler/qqmljstypepropagator.cpp
@@ -340,7 +340,7 @@ void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name, bool isM
"function instead.\n")
.arg(id.location.startLine)
.arg(id.location.startColumn),
- fixLocation, fixString
+ fixLocation, fixString, QString(), false
};
}
break;
@@ -360,7 +360,7 @@ void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name, bool isM
name + QLatin1String(" is a member of a parent element\n")
+ QLatin1String(" You can qualify the access with its id "
"to avoid this warning:\n"),
- fixLocation, (id.isEmpty() ? u"<id>."_qs : (id + u'.'))
+ fixLocation, (id.isEmpty() ? u"<id>."_qs : (id + u'.')), QString(), id.isEmpty()
};
if (id.isEmpty()) {
@@ -677,11 +677,10 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
QQmlJS::SourceLocation fixLocation = getCurrentSourceLocation();
fixLocation.length = 0;
- suggestion.fixes << FixSuggestion::Fix {
- u"Reference it by id instead:"_qs,
- fixLocation,
- id.isEmpty() ? u"<id>."_qs : (id + u'.')
- };
+ suggestion.fixes << FixSuggestion::Fix { u"Reference it by id instead:"_qs,
+ fixLocation,
+ id.isEmpty() ? u"<id>."_qs : (id + u'.'),
+ QString(), id.isEmpty() };
fixLocation = scope->sourceLocation();
fixLocation.length = 0;