2025-04-29 07:24:05 +00:00
|
|
|
// Copyright (C) 2025 The Qt Company Ltd.
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
|
|
|
|
|
|
|
#include "qqmljslintervisitor_p.h"
|
|
|
|
|
|
|
|
QT_BEGIN_NAMESPACE
|
|
|
|
|
2025-04-29 07:38:41 +00:00
|
|
|
using namespace Qt::StringLiterals;
|
|
|
|
using namespace QQmlJS::AST;
|
|
|
|
|
2025-04-29 07:24:05 +00:00
|
|
|
namespace QQmlJS {
|
|
|
|
/*!
|
|
|
|
\internal
|
|
|
|
\class QQmlJS::LinterVisitor
|
|
|
|
Extends QQmlJSImportVisitor with extra warnings that are required for linting but unrelated to
|
|
|
|
QQmlJSImportVisitor actual task that is constructing QQmlJSScopes. One example of such warnings
|
|
|
|
are purely syntactic checks, or style-checks warnings that don't make sense during compilation.
|
|
|
|
*/
|
|
|
|
|
2025-04-29 07:38:41 +00:00
|
|
|
bool LinterVisitor::visit(StringLiteral *sl)
|
|
|
|
{
|
|
|
|
QQmlJSImportVisitor::visit(sl);
|
|
|
|
const QString s = m_logger->code().mid(sl->literalToken.begin(), sl->literalToken.length);
|
|
|
|
|
|
|
|
if (s.contains(QLatin1Char('\r')) || s.contains(QLatin1Char('\n')) || s.contains(QChar(0x2028u))
|
|
|
|
|| s.contains(QChar(0x2029u))) {
|
|
|
|
QString templateString;
|
|
|
|
|
|
|
|
bool escaped = false;
|
|
|
|
const QChar stringQuote = s[0];
|
|
|
|
for (qsizetype i = 1; i < s.size() - 1; i++) {
|
|
|
|
const QChar c = s[i];
|
|
|
|
|
|
|
|
if (c == u'\\') {
|
|
|
|
escaped = !escaped;
|
|
|
|
} else if (escaped) {
|
|
|
|
// If we encounter an escaped quote, unescape it since we use backticks here
|
|
|
|
if (c == stringQuote)
|
|
|
|
templateString.chop(1);
|
|
|
|
|
|
|
|
escaped = false;
|
|
|
|
} else {
|
|
|
|
if (c == u'`')
|
|
|
|
templateString += u'\\';
|
|
|
|
if (c == u'$' && i + 1 < s.size() - 1 && s[i + 1] == u'{')
|
|
|
|
templateString += u'\\';
|
|
|
|
}
|
|
|
|
|
|
|
|
templateString += c;
|
|
|
|
}
|
|
|
|
|
|
|
|
QQmlJSFixSuggestion suggestion = { "Use a template literal instead."_L1, sl->literalToken,
|
|
|
|
u"`" % templateString % u"`" };
|
|
|
|
suggestion.setAutoApplicable();
|
|
|
|
m_logger->log(QStringLiteral("String contains unescaped line terminator which is "
|
|
|
|
"deprecated."),
|
|
|
|
qmlMultilineStrings, sl->literalToken, true, true, suggestion);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2025-04-29 07:24:05 +00:00
|
|
|
} // namespace QQmlJS
|
|
|
|
|
|
|
|
QT_END_NAMESPACE
|