aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrei Golubev <andrei.golubev@qt.io>2022-02-03 13:45:18 +0100
committerAndrei Golubev <andrei.golubev@qt.io>2022-02-12 23:21:29 +0100
commit690b7cb6a2ff86006ed75bb0e09e35d4ceae4c8a (patch)
tree98a4a76a8d061c5c5310245bee177e1c91c652b4
parentf99b2cce65123ac419015968ef3a4f392e55ef6c (diff)
Redesign QQmlJSLogger internals
High-level goal: be able to reuse existing infrastructure "as is" to configure semantic analysis categories in tools (qmllint, qmltc, qmlsc, etc.) To achieve that, simplify the logging to always "log" something, without explicitly specifying the severity. The severity is now baked into the category (and we can extend those to cover different cases) One slight deviation is the cache generation which likes to do its own thing at present. Provide a "forced logging" option where we can specify which severify we want. The hope is that this gets removed at some point Particular list of (noteworthy) changes: * No more "thresholding" by the level (this is rarely needed and is actually questionable). Instead, we can ignore a particular category explicitly * Category levels are repurposed as category severities (at least from the high-level picture that always should've been this way) * log{Warning,Info,Critical} removed. We use category severity instead * "category error" makes zero sense so removed: if our severity is: - QtWarningMsg (qmllint), it is already an "error" - QtCriticalMsg (compilers), it is already an "error" * Align m_output and m_{infos,warnings,errors} stored information * Accept the fact that we don't support QtDebugMsg and QtFatalMsg * Additional categories added to cover for places where the same category would be both an error and not an error Task-number: QTBUG-100052 Change-Id: I3cd5d17d58be204f48428877bed053f756ac40a8 Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r--src/qmlcompiler/qqmljscompiler.cpp21
-rw-r--r--src/qmlcompiler/qqmljsimportvisitor.cpp270
-rw-r--r--src/qmlcompiler/qqmljslinter.cpp19
-rw-r--r--src/qmlcompiler/qqmljslogger.cpp70
-rw-r--r--src/qmlcompiler/qqmljslogger_p.h76
-rw-r--r--src/qmlcompiler/qqmljstypepropagator.cpp54
-rw-r--r--src/qmlcompiler/qqmljstyperesolver.cpp54
-rw-r--r--tests/auto/qml/qmllint/tst_qmllint.cpp13
-rw-r--r--tools/qmlcachegen/qmlcachegen.cpp21
-rw-r--r--tools/qmltc/main.cpp10
-rw-r--r--tools/qmltc/prototype/codegenerator.cpp2
-rw-r--r--tools/qmltc/prototype/qml2cppcontext.h2
-rw-r--r--tools/qmltc/prototype/visitor.cpp4
-rw-r--r--tools/qmltc/qmltccompiler.cpp4
-rw-r--r--tools/qmltc/qmltccompiler.h2
-rw-r--r--tools/qmltc/qmltcvisitor.cpp9
16 files changed, 301 insertions, 330 deletions
diff --git a/src/qmlcompiler/qqmljscompiler.cpp b/src/qmlcompiler/qqmljscompiler.cpp
index f9448f38ac..30b74fe6ee 100644
--- a/src/qmlcompiler/qqmljscompiler.cpp
+++ b/src/qmlcompiler/qqmljscompiler.cpp
@@ -669,26 +669,17 @@ QQmlJS::DiagnosticMessage QQmlJSAotCompiler::diagnose(
const QString &message, QtMsgType type, const QQmlJS::SourceLocation &location) const
{
if (isStrict(m_document)
- && (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
- && m_logger->isCategoryError(Log_Compiler)) {
+ && (type == QtWarningMsg || type == QtCriticalMsg || type == QtFatalMsg)
+ && !m_logger->isCategoryIgnored(Log_Compiler)
+ && m_logger->categoryLevel(Log_Compiler) == QtCriticalMsg) {
qFatal("%s:%d: (strict mode) %s",
qPrintable(QFileInfo(m_resourcePath).fileName()),
location.startLine, qPrintable(message));
}
- switch (type) {
- case QtDebugMsg:
- case QtInfoMsg:
- m_logger->logInfo(message, Log_Compiler, location);
- break;
- case QtWarningMsg:
- m_logger->logWarning(message, Log_Compiler, location);
- break;
- case QtCriticalMsg:
- case QtFatalMsg:
- m_logger->logCritical(message, Log_Compiler, location);
- break;
- }
+ // TODO: this is a special place that explicitly sets the severity through
+ // logger's private function
+ m_logger->log(message, Log_Compiler, location, type);
return QQmlJS::DiagnosticMessage {
message,
diff --git a/src/qmlcompiler/qqmljsimportvisitor.cpp b/src/qmlcompiler/qqmljsimportvisitor.cpp
index 5e4c2e5b9a..a53e24b973 100644
--- a/src/qmlcompiler/qqmljsimportvisitor.cpp
+++ b/src/qmlcompiler/qqmljsimportvisitor.cpp
@@ -220,13 +220,13 @@ void QQmlJSImportVisitor::resolveAliasesAndIds()
if (doRequeue)
continue;
if (foundProperty) {
- m_logger->logWarning(QStringLiteral("Cannot deduce type of alias \"%1\"")
- .arg(property.propertyName()),
- Log_Alias, object->sourceLocation());
+ m_logger->log(QStringLiteral("Cannot deduce type of alias \"%1\"")
+ .arg(property.propertyName()),
+ Log_Alias, object->sourceLocation());
} else {
- m_logger->logWarning(QStringLiteral("Cannot resolve alias \"%1\"")
- .arg(property.propertyName()),
- Log_Alias, object->sourceLocation());
+ m_logger->log(QStringLiteral("Cannot resolve alias \"%1\"")
+ .arg(property.propertyName()),
+ Log_Alias, object->sourceLocation());
}
} else {
property.setType(type);
@@ -279,9 +279,9 @@ void QQmlJSImportVisitor::resolveAliasesAndIds()
for (const auto &property : properties) {
if (!property.isAlias() || property.type())
continue;
- m_logger->logWarning(QStringLiteral("Alias \"%1\" is part of an alias cycle")
- .arg(property.propertyName()),
- Log_Alias, object->sourceLocation());
+ m_logger->log(QStringLiteral("Alias \"%1\" is part of an alias cycle")
+ .arg(property.propertyName()),
+ Log_Alias, object->sourceLocation());
}
}
}
@@ -315,9 +315,9 @@ void QQmlJSImportVisitor::processImportWarnings(
if (warnings.isEmpty())
return;
- m_logger->logWarning(QStringLiteral("Warnings occurred while importing %1:").arg(what),
- Log_Import, srcLocation);
- m_logger->processMessages(warnings, QtWarningMsg, Log_Import);
+ m_logger->log(QStringLiteral("Warnings occurred while importing %1:").arg(what), Log_Import,
+ srcLocation);
+ m_logger->processMessages(warnings, Log_Import);
}
void QQmlJSImportVisitor::importBaseModules()
@@ -411,11 +411,11 @@ void QQmlJSImportVisitor::endVisit(UiProgram *)
unusedImports.remove(import);
for (const auto &import : unusedImports) {
- m_logger->logInfo(QString::fromLatin1("Unused import at %1:%2:%3")
- .arg(m_logger->fileName())
- .arg(import.startLine)
- .arg(import.startColumn),
- Log_UnusedImport, import);
+ m_logger->log(QString::fromLatin1("Unused import at %1:%2:%3")
+ .arg(m_logger->fileName())
+ .arg(import.startLine)
+ .arg(import.startColumn),
+ Log_UnusedImport, import);
}
}
@@ -519,9 +519,8 @@ void QQmlJSImportVisitor::processDefaultProperties()
}
if (!isComponent) {
- m_logger->logWarning(
- QStringLiteral("Cannot assign to non-existent default property"),
- Log_Property, it.value().constFirst()->sourceLocation());
+ m_logger->log(QStringLiteral("Cannot assign to non-existent default property"),
+ Log_Property, it.value().constFirst()->sourceLocation());
}
continue;
@@ -530,7 +529,7 @@ void QQmlJSImportVisitor::processDefaultProperties()
const QQmlJSMetaProperty defaultProp = parentScope->property(defaultPropertyName);
if (it.value().length() > 1 && !defaultProp.isList()) {
- m_logger->logWarning(
+ m_logger->log(
QStringLiteral("Cannot assign multiple objects to a default non-list property"),
Log_Property, it.value().constFirst()->sourceLocation());
}
@@ -554,9 +553,8 @@ void QQmlJSImportVisitor::processDefaultProperties()
continue;
}
- m_logger->logWarning(
- QStringLiteral("Cannot assign to default property of incompatible type"),
- Log_Property, scope->sourceLocation());
+ m_logger->log(QStringLiteral("Cannot assign to default property of incompatible type"),
+ Log_Property, scope->sourceLocation());
}
}
}
@@ -572,10 +570,9 @@ void QQmlJSImportVisitor::processPropertyTypes()
property.setType(propertyType);
type.scope->addOwnProperty(property);
} else {
- m_logger->logWarning(
- property.typeName()
- + QStringLiteral(" was not found. Did you add all import paths?"),
- Log_Import, type.location);
+ m_logger->log(property.typeName()
+ + QStringLiteral(" was not found. Did you add all import paths?"),
+ Log_Import, type.location);
}
}
}
@@ -634,31 +631,28 @@ void QQmlJSImportVisitor::processPropertyBindingObjects()
if (objectBinding.onToken) {
if (childScope->hasInterface(QStringLiteral("QQmlPropertyValueInterceptor"))) {
if (foundInterceptors.contains(uniqueBindingId)) {
- m_logger->logWarning(
- QStringLiteral("Duplicate interceptor on property \"%1\"")
- .arg(propertyName),
- Log_Property, objectBinding.location);
+ m_logger->log(QStringLiteral("Duplicate interceptor on property \"%1\"")
+ .arg(propertyName),
+ Log_Property, objectBinding.location);
} else {
foundInterceptors.insert(uniqueBindingId);
}
} else if (childScope->hasInterface(QStringLiteral("QQmlPropertyValueSource"))) {
if (foundValueSources.contains(uniqueBindingId)) {
- m_logger->logWarning(
- QStringLiteral("Duplicate value source on property \"%1\"")
- .arg(propertyName),
- Log_Property, objectBinding.location);
+ m_logger->log(QStringLiteral("Duplicate value source on property \"%1\"")
+ .arg(propertyName),
+ Log_Property, objectBinding.location);
} else if (foundObjects.contains(uniqueBindingId)
|| foundLiterals.contains(uniqueBindingId)) {
- m_logger->logWarning(
- QStringLiteral("Cannot combine value source and binding on "
- "property \"%1\"")
- .arg(propertyName),
- Log_Property, objectBinding.location);
+ m_logger->log(QStringLiteral("Cannot combine value source and binding on "
+ "property \"%1\"")
+ .arg(propertyName),
+ Log_Property, objectBinding.location);
} else {
foundValueSources.insert(uniqueBindingId);
}
} else {
- m_logger->logWarning(
+ m_logger->log(
QStringLiteral("On-binding for property \"%1\" has wrong type \"%2\"")
.arg(propertyName)
.arg(typeName),
@@ -667,7 +661,7 @@ void QQmlJSImportVisitor::processPropertyBindingObjects()
} else {
// TODO: Warn here if binding.hasValue() is true
if (foundValueSources.contains(uniqueBindingId)) {
- m_logger->logWarning(
+ m_logger->log(
QStringLiteral(
"Cannot combine value source and binding on property \"%1\"")
.arg(propertyName),
@@ -680,28 +674,27 @@ void QQmlJSImportVisitor::processPropertyBindingObjects()
// If the current scope is not fully resolved we cannot tell whether the property exists
// or not (we already warn elsewhere)
} else if (!property.isValid()) {
- m_logger->logWarning(QStringLiteral("Property \"%1\" is invalid or does not exist")
- .arg(propertyName),
- Log_Property, objectBinding.location);
+ m_logger->log(QStringLiteral("Property \"%1\" is invalid or does not exist")
+ .arg(propertyName),
+ Log_Property, objectBinding.location);
} else if (property.type().isNull() || !property.type()->isFullyResolved()) {
// Property type is not fully resolved we cannot tell any more than this
- m_logger->logWarning(
- QStringLiteral("Property \"%1\" has incomplete type \"%2\". You may be "
- "missing an import.")
- .arg(propertyName)
- .arg(property.typeName()),
- Log_Property, objectBinding.location);
+ m_logger->log(QStringLiteral("Property \"%1\" has incomplete type \"%2\". You may be "
+ "missing an import.")
+ .arg(propertyName)
+ .arg(property.typeName()),
+ Log_Property, objectBinding.location);
} else if (!childScope->isFullyResolved()) {
// If the childScope type is not fully resolved we cannot tell whether the type is
// incompatible (we already warn elsewhere)
} else {
// the type is incompatible
- m_logger->logWarning(QStringLiteral("Property \"%1\" of type \"%2\" is assigned an "
- "incompatible type \"%3\"")
- .arg(propertyName)
- .arg(property.typeName())
- .arg(getScopeName(childScope, QQmlJSScope::QMLScope)),
- Log_Property, objectBinding.location);
+ m_logger->log(QStringLiteral("Property \"%1\" of type \"%2\" is assigned an "
+ "incompatible type \"%3\"")
+ .arg(propertyName)
+ .arg(property.typeName())
+ .arg(getScopeName(childScope, QQmlJSScope::QMLScope)),
+ Log_Property, objectBinding.location);
}
}
}
@@ -710,7 +703,7 @@ void QQmlJSImportVisitor::checkRequiredProperties()
{
for (const auto &required : m_requiredProperties) {
if (!required.scope->hasProperty(required.name)) {
- m_logger->logWarning(
+ m_logger->log(
QStringLiteral("Property \"%1\" was marked as required but does not exist.")
.arg(required.name),
Log_Required, required.location);
@@ -781,7 +774,7 @@ void QQmlJSImportVisitor::checkRequiredProperties()
message += QStringLiteral(" (marked as required by %3)")
.arg(requiredScopeName);
- m_logger->logWarning(message, Log_Required, defScope->sourceLocation());
+ m_logger->log(message, Log_Required, defScope->sourceLocation());
}
}
prevRequiredScope = requiredScope;
@@ -816,22 +809,20 @@ void QQmlJSImportVisitor::processPropertyBindings()
}
}
- m_logger->logWarning(
- QStringLiteral("Binding assigned to \"%1\", but no property \"%1\" "
- "exists in the current element.")
- .arg(name),
- Log_Type, location, true, true, fixSuggestion);
+ m_logger->log(QStringLiteral("Binding assigned to \"%1\", but no property \"%1\" "
+ "exists in the current element.")
+ .arg(name),
+ Log_Type, location, true, true, fixSuggestion);
continue;
}
const auto property = scope->property(name);
if (!property.type()) {
- m_logger->logWarning(
- QStringLiteral("No type found for property \"%1\". This may be due "
- "to a missing import statement or incomplete "
- "qmltypes files.")
- .arg(name),
- Log_Type, location);
+ m_logger->log(QStringLiteral("No type found for property \"%1\". This may be due "
+ "to a missing import statement or incomplete "
+ "qmltypes files.")
+ .arg(name),
+ Log_Type, location);
}
const auto &annotations = property.annotations();
@@ -849,7 +840,7 @@ void QQmlJSImportVisitor::processPropertyBindings()
if (!deprecation.reason.isEmpty())
message.append(QStringLiteral(" (Reason: %1)").arg(deprecation.reason));
- m_logger->logWarning(message, Log_Deprecation, location);
+ m_logger->log(message, Log_Deprecation, location);
}
}
}
@@ -928,9 +919,9 @@ void QQmlJSImportVisitor::checkSignals()
.arg(pair.first, pair.second.join(u", ")) } } };
}
- m_logger->logWarning(QStringLiteral("no matching signal found for handler \"%1\"")
- .arg(pair.first),
- Log_UnqualifiedAccess, location, true, true, fix);
+ m_logger->log(QStringLiteral("no matching signal found for handler \"%1\"")
+ .arg(pair.first),
+ Log_UnqualifiedAccess, location, true, true, fix);
continue;
}
@@ -938,10 +929,10 @@ void QQmlJSImportVisitor::checkSignals()
const QStringList signalParameters = signalMethod->parameterNames();
if (pair.second.length() > signalParameters.length()) {
- m_logger->logWarning(QStringLiteral("Signal handler for \"%2\" has more formal"
- " parameters than the signal it handles.")
- .arg(pair.first),
- Log_Signal, location);
+ m_logger->log(QStringLiteral("Signal handler for \"%2\" has more formal"
+ " parameters than the signal it handles.")
+ .arg(pair.first),
+ Log_Signal, location);
continue;
}
@@ -951,13 +942,13 @@ void QQmlJSImportVisitor::checkSignals()
if (j == i || j < 0)
continue;
- m_logger->logWarning(QStringLiteral("Parameter %1 to signal handler for \"%2\""
- " is called \"%3\". The signal has a parameter"
- " of the same name in position %4.")
- .arg(i + 1)
- .arg(pair.first, handlerParameter)
- .arg(j + 1),
- Log_Signal, location);
+ m_logger->log(QStringLiteral("Parameter %1 to signal handler for \"%2\""
+ " is called \"%3\". The signal has a parameter"
+ " of the same name in position %4.")
+ .arg(i + 1)
+ .arg(pair.first, handlerParameter)
+ .arg(j + 1),
+ Log_Signal, location);
}
}
}
@@ -1014,10 +1005,10 @@ void QQmlJSImportVisitor::breakInheritanceCycles(const QQmlJSScope::Ptr &origina
inheritenceCycle.append(seen->baseTypeName());
}
- m_logger->logWarning(QStringLiteral("%1 is part of an inheritance cycle: %2")
- .arg(scope->internalName())
- .arg(inheritenceCycle),
- Log_InheritanceCycle);
+ m_logger->log(QStringLiteral("%1 is part of an inheritance cycle: %2")
+ .arg(scope->internalName())
+ .arg(inheritenceCycle),
+ Log_InheritanceCycle, scope->sourceLocation());
originalScope->clearBaseType();
break;
}
@@ -1026,12 +1017,11 @@ void QQmlJSImportVisitor::breakInheritanceCycles(const QQmlJSScope::Ptr &origina
const auto newScope = scope->baseType();
if (newScope.isNull() && !scope->baseTypeName().isEmpty()) {
- m_logger->logWarning(
- scope->baseTypeName()
- + QStringLiteral(" was not found. Did you add all import paths?"),
- Log_Import, scope->sourceLocation(), true, true,
- QQmlJSUtils::didYouMean(scope->baseTypeName(), m_rootScopeImports.keys(),
- scope->sourceLocation()));
+ m_logger->log(scope->baseTypeName()
+ + QStringLiteral(" was not found. Did you add all import paths?"),
+ Log_Import, scope->sourceLocation(), true, true,
+ QQmlJSUtils::didYouMean(scope->baseTypeName(), m_rootScopeImports.keys(),
+ scope->sourceLocation()));
}
scope = newScope;
@@ -1051,7 +1041,7 @@ void QQmlJSImportVisitor::checkDeprecation(const QQmlJSScope::ConstPtr &original
if (!deprecation.reason.isEmpty())
message.append(QStringLiteral(" (Reason: %1)").arg(deprecation.reason));
- m_logger->logWarning(message, Log_Deprecation, originalScope->sourceLocation());
+ m_logger->log(message, Log_Deprecation, originalScope->sourceLocation());
}
}
}
@@ -1072,12 +1062,12 @@ void QQmlJSImportVisitor::checkGroupedAndAttachedScopes(QQmlJSScope::ConstPtr sc
case QQmlJSScope::GroupedPropertyScope:
case QQmlJSScope::AttachedPropertyScope:
if (!childScope->baseType()) {
- m_logger->logWarning(QStringLiteral("unknown %1 property scope %2.")
- .arg(type == QQmlJSScope::GroupedPropertyScope
- ? QStringLiteral("grouped")
- : QStringLiteral("attached"),
- childScope->internalName()),
- Log_UnqualifiedAccess, childScope->sourceLocation());
+ m_logger->log(QStringLiteral("unknown %1 property scope %2.")
+ .arg(type == QQmlJSScope::GroupedPropertyScope
+ ? QStringLiteral("grouped")
+ : QStringLiteral("attached"),
+ childScope->internalName()),
+ Log_UnqualifiedAccess, childScope->sourceLocation());
}
children.append(childScope->childScopes());
default:
@@ -1121,10 +1111,10 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::StringLiteral *sl)
if (s.contains(QLatin1Char('\r')) || s.contains(QLatin1Char('\n')) || s.contains(QChar(0x2028u))
|| s.contains(QChar(0x2029u))) {
- m_logger->logWarning(QStringLiteral("String contains unescaped line terminator which is "
- "deprecated. Use a template "
- "literal instead."),
- Log_MultilineString, sl->literalToken);
+ m_logger->log(QStringLiteral("String contains unescaped line terminator which is "
+ "deprecated. Use a template "
+ "literal instead."),
+ Log_MultilineString, sl->literalToken);
}
return true;
@@ -1181,8 +1171,8 @@ void QQmlJSImportVisitor::endVisit(UiObjectDefinition *)
bool QQmlJSImportVisitor::visit(UiInlineComponent *component)
{
if (!m_inlineComponentName.isNull()) {
- m_logger->logWarning(u"Nested inline components are not supported"_qs, Log_Syntax,
- component->firstSourceLocation());
+ m_logger->log(u"Nested inline components are not supported"_qs, Log_Syntax,
+ component->firstSourceLocation());
return true;
}
@@ -1234,9 +1224,9 @@ bool QQmlJSImportVisitor::visit(UiPublicMember *publicMember)
if (const auto idExpression = cast<IdentifierExpression *>(node)) {
aliasExpr.prepend(idExpression->name.toString());
} else {
- m_logger->logWarning(QStringLiteral("Invalid alias expression. Only IDs and field "
- "member expressions can be aliased."),
- Log_Alias, expression->firstSourceLocation());
+ m_logger->log(QStringLiteral("Invalid alias expression. Only IDs and field "
+ "member expressions can be aliased."),
+ Log_Alias, expression->firstSourceLocation());
}
} else {
const auto name = publicMember->memberType->name.toString();
@@ -1366,8 +1356,8 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiSourceElement *srcElement)
bool QQmlJSImportVisitor::visit(QQmlJS::AST::FunctionDeclaration *fdecl)
{
- m_logger->logWarning(u"Declared function \"%1\""_qs.arg(fdecl->name), Log_ControlsSanity,
- fdecl->firstSourceLocation());
+ m_logger->log(u"Declared function \"%1\""_qs.arg(fdecl->name), Log_ControlsSanity,
+ fdecl->firstSourceLocation());
visitFunctionExpressionHelper(fdecl);
return true;
}
@@ -1527,10 +1517,12 @@ void QQmlJSImportVisitor::handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scri
if (const auto *idExpression = cast<IdentifierExpression *>(statement->expression))
return idExpression->name.toString();
else if (const auto *idString = cast<StringLiteral *>(statement->expression)) {
- m_logger->logInfo(u"ids do not need quotation marks"_qs, Log_Syntax, idString->firstSourceLocation());
+ m_logger->log(u"ids do not need quotation marks"_qs, Log_SyntaxIdQuotation,
+ idString->firstSourceLocation());
return idString->value.toString();
}
- m_logger->logWarning(u"Failed to parse id"_qs, Log_Syntax, statement->expression->firstSourceLocation());
+ m_logger->log(u"Failed to parse id"_qs, Log_Syntax,
+ statement->expression->firstSourceLocation());
return QString();
}();
@@ -1542,14 +1534,11 @@ void QQmlJSImportVisitor::handleIdDeclaration(QQmlJS::AST::UiScriptBinding *scri
auto otherLocation = otherScopeWithID->sourceLocation();
// critical because subsequent analysis cannot cope with messed up ids
// and the file is invalid
- m_logger->logCritical(
- u"Found a duplicated id. id %1 was first declared at %2:%3"_qs.arg(
- name,
- QString::number(otherLocation.startLine),
- QString::number(otherLocation.startColumn)),
- Log_Syntax, // ??
- scriptBinding->firstSourceLocation()
- );
+ m_logger->log(u"Found a duplicated id. id %1 was first declared at %2:%3"_qs.arg(
+ name, QString::number(otherLocation.startLine),
+ QString::number(otherLocation.startColumn)),
+ Log_Syntax, // ??
+ scriptBinding->firstSourceLocation());
}
}
if (!name.isEmpty())
@@ -1580,8 +1569,8 @@ bool QQmlJSImportVisitor::visit(UiScriptBinding *scriptBinding)
auto name = group->name;
if (id && id->name.toString() == u"anchors")
- m_logger->logWarning(u"Using anchors here"_qs, Log_ControlsSanity,
- scriptBinding->firstSourceLocation());
+ m_logger->log(u"Using anchors here"_qs, Log_ControlsSanity,
+ scriptBinding->firstSourceLocation());
const auto signal = QQmlJSUtils::signalName(name);
@@ -1604,8 +1593,8 @@ bool QQmlJSImportVisitor::visit(UiScriptBinding *scriptBinding)
}
}
- m_logger->logWarning(u"Declared signal handler \"%1\""_qs.arg(name), Log_ControlsSanity,
- scriptBinding->firstSourceLocation());
+ m_logger->log(u"Declared signal handler \"%1\""_qs.arg(name), Log_ControlsSanity,
+ scriptBinding->firstSourceLocation());
m_signals[m_currentScope].append({ m_savedBindingOuterScope, group->firstSourceLocation(),
qMakePair(name.toString(), signalParameters) });
@@ -1803,10 +1792,14 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiImport *import)
bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiPragma *pragma)
{
- // If a file uses pragma Strict it expects to be compiled, so automatically enable compiler
- // warnings unless the user has explicitly set the level.
- if (pragma->name == u"Strict"_qs && !m_logger->wasCategoryChanged(Log_Compiler))
+ // If a file uses pragma Strict, it expects to be compiled, so automatically
+ // enable compiler warnings unless the level is set explicitly already (e.g.
+ // by the user).
+ if (pragma->name == u"Strict"_qs && !m_logger->wasCategoryChanged(Log_Compiler)) {
+ // TODO: the logic here is rather complicated and may be buggy
m_logger->setCategoryLevel(Log_Compiler, QtWarningMsg);
+ m_logger->setCategoryIgnored(Log_Compiler, false);
+ }
if (pragma->name == u"Singleton")
m_rootIsSingleton = true;
@@ -1816,8 +1809,8 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::UiPragma *pragma)
void QQmlJSImportVisitor::throwRecursionDepthError()
{
- m_logger->logCritical(QStringLiteral("Maximum statement or expression depth exceeded"),
- Log_RecursionDepthError);
+ m_logger->log(QStringLiteral("Maximum statement or expression depth exceeded"),
+ Log_RecursionDepthError, QQmlJS::SourceLocation());
}
bool QQmlJSImportVisitor::visit(QQmlJS::AST::ClassDeclaration *ast)
@@ -1906,11 +1899,10 @@ bool QQmlJSImportVisitor::visit(QQmlJS::AST::WithStatement *ast)
enterEnvironment(QQmlJSScope::JSLexicalScope, QStringLiteral("with"),
ast->firstSourceLocation());
- m_logger->logWarning(
- QStringLiteral("with statements are strongly discouraged in QML "
- "and might cause false positives when analysing unqualified "
- "identifiers"),
- Log_WithStatement, ast->firstSourceLocation());
+ m_logger->log(QStringLiteral("with statements are strongly discouraged in QML "
+ "and might cause false positives when analysing unqualified "
+ "identifiers"),
+ Log_WithStatement, ast->firstSourceLocation());
return true;
}
@@ -2031,7 +2023,7 @@ void QQmlJSImportVisitor::endVisit(QQmlJS::AST::UiObjectBinding *uiob)
}
if (foundIds) {
- m_logger->logWarning(
+ m_logger->log(
u"Cannot defer property assignment to \"%1\". Assigning an id to an object or one of its sub-objects bound to a deferred property will make the assignment immediate."_qs
.arg(propertyName),
Log_DeferredPropertyId, uiob->firstSourceLocation());
diff --git a/src/qmlcompiler/qqmljslinter.cpp b/src/qmlcompiler/qqmljslinter.cpp
index c50740750e..959b7c3f03 100644
--- a/src/qmlcompiler/qqmljslinter.cpp
+++ b/src/qmlcompiler/qqmljslinter.cpp
@@ -56,7 +56,7 @@ public:
QQmlJS::SourceLocation accessLocation) override
{
Q_UNUSED(fileName)
- m_logger->logWarning(
+ m_logger->log(
u"Variable \"%1\" is used here before its declaration. The declaration is at %2:%3."_qs
.arg(name)
.arg(declarationLocation.startLine)
@@ -101,8 +101,8 @@ void QQmlJSLinter::parseComments(QQmlJSLogger *logger,
if (option != logger->options().constEnd())
categories << option->m_category;
else
- logger->logWarning(u"qmllint directive on unknown category \"%1\""_qs.arg(category),
- Log_Syntax, loc);
+ logger->log(u"qmllint directive on unknown category \"%1\""_qs.arg(category),
+ Log_Syntax, loc);
}
if (categories.isEmpty()) {
@@ -129,8 +129,8 @@ void QQmlJSLinter::parseComments(QQmlJSLogger *logger,
} else if (command == u"enable"_qs) {
enablesPerLine[loc.startLine + 1] |= categories;
} else {
- logger->logWarning(u"Invalid qmllint directive \"%1\" provided"_qs.arg(command),
- Log_Syntax, loc);
+ logger->log(u"Invalid qmllint directive \"%1\" provided"_qs.arg(command), Log_Syntax,
+ loc);
}
}
@@ -314,7 +314,7 @@ bool QQmlJSLinter::lintFile(const QString &filename, const QString *fileContents
if (!it.value().m_changed)
continue;
- m_logger->setCategoryError(it.value().m_category, it.value().m_error);
+ m_logger->setCategoryIgnored(it.value().m_category, it.value().m_ignored);
m_logger->setCategoryLevel(it.value().m_category, it.value().m_level);
}
@@ -361,10 +361,9 @@ bool QQmlJSLinter::lintFile(const QString &filename, const QString *fileContents
QList<QQmlJS::DiagnosticMessage> warnings = m_importer.takeGlobalWarnings();
if (!warnings.isEmpty()) {
- m_logger->logWarning(
- QStringLiteral("Type warnings occurred while evaluating file:"),
- Log_Import);
- m_logger->processMessages(warnings, QtWarningMsg, Log_Import);
+ m_logger->log(QStringLiteral("Type warnings occurred while evaluating file:"),
+ Log_Import, QQmlJS::SourceLocation());
+ m_logger->processMessages(warnings, Log_Import);
}
success &= !m_logger->hasWarnings() && !m_logger->hasErrors();
diff --git a/src/qmlcompiler/qqmljslogger.cpp b/src/qmlcompiler/qqmljslogger.cpp
index d7bdc714a6..54cbd6e45d 100644
--- a/src/qmlcompiler/qqmljslogger.cpp
+++ b/src/qmlcompiler/qqmljslogger.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2021 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -34,10 +34,10 @@ const QMap<QString, QQmlJSLogger::Option> &QQmlJSLogger::options() {
static QMap<QString, QQmlJSLogger::Option> optionsMap = {
{ QStringLiteral("required"),
QQmlJSLogger::Option(Log_Required, QStringLiteral("RequiredProperty"),
- QStringLiteral("Warn about required properties"), QtInfoMsg) },
+ QStringLiteral("Warn about required properties"), QtWarningMsg) },
{ QStringLiteral("alias"),
QQmlJSLogger::Option(Log_Alias, QStringLiteral("PropertyAlias"),
- QStringLiteral("Warn about alias errors"), QtInfoMsg) },
+ QStringLiteral("Warn about alias errors"), QtWarningMsg) },
{ QStringLiteral("import"),
QQmlJSLogger::Option(Log_Import, QStringLiteral("ImportFailure"),
QStringLiteral("Warn about failing imports and deprecated qmltypes"),
@@ -49,7 +49,7 @@ const QMap<QString, QQmlJSLogger::Option> &QQmlJSLogger::options() {
QtWarningMsg) },
{ QStringLiteral("inheritance-cycle"),
QQmlJSLogger::Option(Log_InheritanceCycle, QStringLiteral("InheritanceCycle"),
- QStringLiteral("Warn about inheritance cycles"), QtInfoMsg) },
+ QStringLiteral("Warn about inheritance cycles"), QtWarningMsg) },
{ QStringLiteral("deprecated"),
QQmlJSLogger::Option(Log_Deprecation, QStringLiteral("Deprecated"),
QStringLiteral("Warn about deprecated properties and types"),
@@ -64,13 +64,13 @@ const QMap<QString, QQmlJSLogger::Option> &QQmlJSLogger::options() {
QtWarningMsg) },
{ QStringLiteral("property"),
QQmlJSLogger::Option(Log_Property, QStringLiteral("UnknownProperty"),
- QStringLiteral("Warn about unknown properties"), QtInfoMsg) },
+ QStringLiteral("Warn about unknown properties"), QtWarningMsg) },
{ QStringLiteral("deferred-property-id"),
QQmlJSLogger::Option(
Log_DeferredPropertyId, QStringLiteral("DeferredPropertyId"),
QStringLiteral(
"Warn about making deferred properties immediate by giving them an id."),
- QtInfoMsg) },
+ QtWarningMsg) },
{ QStringLiteral("unqualified"),
QQmlJSLogger::Option(
Log_UnqualifiedAccess, QStringLiteral("UnqualifiedAccess"),
@@ -78,24 +78,23 @@ const QMap<QString, QQmlJSLogger::Option> &QQmlJSLogger::options() {
QtWarningMsg) },
{ QStringLiteral("unused-imports"),
QQmlJSLogger::Option(Log_UnusedImport, QStringLiteral("UnusedImports"),
- QStringLiteral("Warn about unused imports"), QtInfoMsg, false) },
+ QStringLiteral("Warn about unused imports"), QtInfoMsg) },
{ QStringLiteral("multiline-strings"),
QQmlJSLogger::Option(Log_MultilineString, QStringLiteral("MultilineStrings"),
- QStringLiteral("Warn about multiline strings"), QtInfoMsg, false) },
+ QStringLiteral("Warn about multiline strings"), QtInfoMsg) },
{ QStringLiteral("compiler"),
QQmlJSLogger::Option(Log_Compiler, QStringLiteral("CompilerWarnings"),
- QStringLiteral("Warn about compiler issues"), QtCriticalMsg,
- false) },
+ QStringLiteral("Warn about compiler issues"), QtCriticalMsg, true) },
{ QStringLiteral("controls-sanity"),
QQmlJSLogger::Option(
Log_ControlsSanity, QStringLiteral("ControlsSanity"),
QStringLiteral("Performance checks used for QuickControl's implementation"),
- QtCriticalMsg, false) },
+ QtCriticalMsg, true) },
{ QStringLiteral("multiple-attached-objects"),
QQmlJSLogger::Option(
Log_AttachedPropertyReuse, QStringLiteral("AttachedPropertyReuse"),
QStringLiteral("Warn if attached types from parent components aren't reused"),
- QtCriticalMsg, false) }
+ QtCriticalMsg, true) }
};
return optionsMap;
@@ -106,20 +105,20 @@ QQmlJSLogger::QQmlJSLogger()
const auto &opt = options();
for (auto it = opt.cbegin(); it != opt.cend(); ++it) {
m_categoryLevels[it.value().m_category] = it.value().m_level;
- m_categoryError[it.value().m_category] = it.value().m_error;
+ m_categoryIgnored[it.value().m_category] = it.value().m_ignored;
}
// These have to be set up manually since we don't expose it as an option
- m_categoryLevels[Log_RecursionDepthError] = QtInfoMsg;
- m_categoryError[Log_RecursionDepthError] = true;
- m_categoryLevels[Log_Syntax] = QtInfoMsg;
- m_categoryError[Log_Syntax] = true;
+ m_categoryLevels[Log_RecursionDepthError] = QtCriticalMsg;
+ m_categoryLevels[Log_Syntax] = QtWarningMsg; // TODO: because we usually report it as a warning!
+ m_categoryLevels[Log_SyntaxIdQuotation] = QtWarningMsg;
+ m_categoryLevels[Log_SyntaxDuplicateIds] = QtCriticalMsg;
// setup color output
m_output.insertMapping(QtCriticalMsg, QColorOutput::RedForeground);
- m_output.insertMapping(QtWarningMsg, QColorOutput::PurpleForeground);
+ m_output.insertMapping(QtWarningMsg, QColorOutput::PurpleForeground); // Yellow?
m_output.insertMapping(QtInfoMsg, QColorOutput::BlueForeground);
- m_output.insertMapping(QtDebugMsg, QColorOutput::GreenForeground);
+ m_output.insertMapping(QtDebugMsg, QColorOutput::GreenForeground); // None?
}
static bool isMsgTypeLess(QtMsgType a, QtMsgType b)
@@ -136,9 +135,11 @@ void QQmlJSLogger::log(const QString &message, QQmlJSLoggerCategory category,
const QQmlJS::SourceLocation &srcLocation, QtMsgType type, bool showContext,
bool showFileName, const std::optional<FixSuggestion> &suggestion)
{
- if (isMsgTypeLess(type, m_categoryLevels[category]))
+ if (isCategoryIgnored(category))
return;
+ // Note: assume \a type is the type we should prefer for logging
+
if (srcLocation.isValid() && m_ignoredWarnings[srcLocation.startLine].contains(category))
return;
@@ -153,26 +154,21 @@ void QQmlJSLogger::log(const QString &message, QQmlJSLoggerCategory category,
if (!prefix.isEmpty())
prefix.append(QLatin1Char(' '));
- m_output.writePrefixedMessage(prefix + message, type);
-
- QtMsgType machineType = isMsgTypeLess(QtWarningMsg, type) ? QtCriticalMsg : QtInfoMsg;
+ // Note: we do the clamping to [Info, Critical] range since our logger only
+ // supports 3 categories
+ type = std::clamp(type, QtInfoMsg, QtCriticalMsg, isMsgTypeLess);
- // If this is a category that produces error codes, we need to up all the messages to at least a
- // warning level
- if (isCategoryError(category)) {
- if (isMsgTypeLess(type, QtWarningMsg))
- machineType = QtWarningMsg;
- else
- machineType = type;
- }
+ // Note: since we clamped our \a type, the output message is not printed
+ // exactly like it was requested, bear with us
+ m_output.writePrefixedMessage(prefix + message, type);
Message diagMsg;
diagMsg.message = message;
diagMsg.loc = srcLocation;
- diagMsg.type = machineType;
+ diagMsg.type = type;
diagMsg.fixSuggestion = suggestion;
- switch (machineType) {
+ switch (type) {
case QtWarningMsg: m_warnings.push_back(diagMsg); break;
case QtCriticalMsg: m_errors.push_back(diagMsg); break;
case QtInfoMsg: m_infos.push_back(diagMsg); break;
@@ -187,15 +183,17 @@ void QQmlJSLogger::log(const QString &message, QQmlJSLoggerCategory category,
}
void QQmlJSLogger::processMessages(const QList<QQmlJS::DiagnosticMessage> &messages,
- QtMsgType level, QQmlJSLoggerCategory category)
+ QQmlJSLoggerCategory category)
{
- if (isMsgTypeLess(level, m_categoryLevels[category]) || messages.isEmpty())
+ if (messages.isEmpty() || isCategoryIgnored(category))
return;
m_output.write(QStringLiteral("---\n"));
+ // TODO: we should instead respect message's category here (potentially, it
+ // should hold a category instead of type)
for (const QQmlJS::DiagnosticMessage &message : messages)
- logWarning(message.message, category, QQmlJS::SourceLocation(), false, false);
+ log(message.message, category, QQmlJS::SourceLocation(), false, false);
m_output.write(QStringLiteral("---\n\n"));
}
diff --git a/src/qmlcompiler/qqmljslogger_p.h b/src/qmlcompiler/qqmljslogger_p.h
index 0792cd434b..462854225f 100644
--- a/src/qmlcompiler/qqmljslogger_p.h
+++ b/src/qmlcompiler/qqmljslogger_p.h
@@ -107,6 +107,8 @@ enum QQmlJSLoggerCategory {
Log_UnusedImport,
Log_MultilineString,
Log_Syntax,
+ Log_SyntaxIdQuotation,
+ Log_SyntaxDuplicateIds,
Log_Compiler,
Log_ControlsSanity,
Log_AttachedPropertyReuse,
@@ -137,31 +139,32 @@ public:
{
Option() = default;
Option(QQmlJSLoggerCategory category, QString settingsName, const QString &description,
- QtMsgType level, bool error = true)
+ QtMsgType level, bool ignored = false)
: m_category(category),
m_settingsName(settingsName),
m_description(description),
m_level(level),
- m_error(error)
+ m_ignored(ignored)
{
}
QQmlJSLoggerCategory m_category;
QString m_settingsName;
QString m_description;
QtMsgType m_level;
- bool m_error;
+ bool m_ignored;
bool m_changed = false;
QString levelToString() const {
+ // TODO:: this only makes sense to qmllint
+ Q_ASSERT(m_ignored || m_level != QtCriticalMsg);
+ if (m_ignored)
+ return QStringLiteral("disable");
+
switch (m_level) {
case QtInfoMsg:
- return m_error ? QStringLiteral("warning") : QStringLiteral("info");
+ return QStringLiteral("info");
case QtWarningMsg:
- // TODO: This case doesn't cleanly map onto any warning level yet
- // this has to be handled in the option overhaul
- return m_error ? QStringLiteral("warning") : QStringLiteral("info");
- case QtCriticalMsg:
- return QStringLiteral("disable");
+ return QStringLiteral("warning");
default:
Q_UNREACHABLE();
break;
@@ -170,14 +173,14 @@ public:
bool setLevel(const QString &level) {
if (level == QStringLiteral("disable")) {
- m_level = QtCriticalMsg;
- m_error = false;
+ m_level = QtCriticalMsg; // TODO: only so for consistency with previous logic
+ m_ignored = true;
} else if (level == QStringLiteral("info")) {
m_level = QtInfoMsg;
- m_error = false;
+ m_ignored = false;
} else if (level == QStringLiteral("warning")) {
- m_level = QtInfoMsg;
- m_error = true;
+ m_level = QtWarningMsg;
+ m_ignored = false;
} else {
return false;
}
@@ -206,10 +209,13 @@ public:
m_categoryChanged[category] = true;
}
- bool isCategoryError(QQmlJSLoggerCategory category) const { return m_categoryError[category]; }
- void setCategoryError(QQmlJSLoggerCategory category, bool error)
+ bool isCategoryIgnored(QQmlJSLoggerCategory category) const
+ {
+ return m_categoryIgnored[category];
+ }
+ void setCategoryIgnored(QQmlJSLoggerCategory category, bool error)
{
- m_categoryError[category] = error;
+ m_categoryIgnored[category] = error;
m_categoryChanged[category] = true;
}
@@ -218,31 +224,22 @@ public:
return m_categoryChanged[category];
}
- void logInfo(const QString &message, QQmlJSLoggerCategory category,
- const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation(),
- bool showContext = true, bool showFileName = true,
- const std::optional<FixSuggestion> &suggestion = {})
- {
- log(message, category, srcLocation, QtInfoMsg, showContext, showFileName, suggestion);
- }
+ /*! \internal
- void logWarning(const QString &message, QQmlJSLoggerCategory category,
- const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation(),
- bool showContext = true, bool showFileName = true,
- const std::optional<FixSuggestion> &suggestion = {})
- {
- log(message, category, srcLocation, QtWarningMsg, showContext, showFileName, suggestion);
- }
+ Logs \a message with severity deduced from \a category. Prefer using
+ this function in most cases.
- void logCritical(const QString &message, QQmlJSLoggerCategory category,
- const QQmlJS::SourceLocation &srcLocation = QQmlJS::SourceLocation(),
- bool showContext = true, bool showFileName = true,
- const std::optional<FixSuggestion> &suggestion = {})
+ \sa setCategoryLevel
+ */
+ void log(const QString &message, QQmlJSLoggerCategory category,
+ const QQmlJS::SourceLocation &srcLocation, bool showContext = true,
+ bool showFileName = true, const std::optional<FixSuggestion> &suggestion = {})
{
- log(message, category, srcLocation, QtCriticalMsg, showContext, showFileName, suggestion);
+ log(message, category, srcLocation, m_categoryLevels[category], showContext, showFileName,
+ suggestion);
}
- void processMessages(const QList<QQmlJS::DiagnosticMessage> &messages, QtMsgType level,
+ void processMessages(const QList<QQmlJS::DiagnosticMessage> &messages,
QQmlJSLoggerCategory category);
void ignoreWarnings(uint32_t line, const QSet<QQmlJSLoggerCategory> &categories)
@@ -273,13 +270,16 @@ private:
QColorOutput m_output;
QtMsgType m_categoryLevels[QQmlJSLoggerCategory_Last + 1] = {};
- bool m_categoryError[QQmlJSLoggerCategory_Last + 1] = {};
+ bool m_categoryIgnored[QQmlJSLoggerCategory_Last + 1] = {};
bool m_categoryChanged[QQmlJSLoggerCategory_Last + 1] = {};
QList<Message> m_infos;
QList<Message> m_warnings;
QList<Message> m_errors;
QHash<uint32_t, QSet<QQmlJSLoggerCategory>> m_ignoredWarnings;
+
+ // the compiler needs private log() function at the moment
+ friend class QQmlJSAotCompiler;
};
QT_END_NAMESPACE
diff --git a/src/qmlcompiler/qqmljstypepropagator.cpp b/src/qmlcompiler/qqmljstypepropagator.cpp
index 6072393e0f..0389cbeb06 100644
--- a/src/qmlcompiler/qqmljstypepropagator.cpp
+++ b/src/qmlcompiler/qqmljstypepropagator.cpp
@@ -80,9 +80,8 @@ QQmlJSCompilePass::InstructionAnnotations QQmlJSTypePropagator::run(
return;
#define INSTR_PROLOGUE_NOT_IMPLEMENTED_IGNORE() \
- m_logger->logWarning( \
- u"Instruction \"%1\" not implemented"_qs.arg(QString::fromUtf8(__func__)), \
- Log_Compiler); \
+ m_logger->log(u"Instruction \"%1\" not implemented"_qs.arg(QString::fromUtf8(__func__)), \
+ Log_Compiler, QQmlJS::SourceLocation()); \
return;
void QQmlJSTypePropagator::generate_Ret()
@@ -101,10 +100,10 @@ void QQmlJSTypePropagator::generate_Ret()
.arg(m_state.accumulatorIn.descriptiveName(),
m_returnType.descriptiveName()));
- m_logger->logWarning(u"Cannot assign binding of type %1 to %2"_qs.arg(
- m_typeResolver->containedTypeName(m_state.accumulatorIn),
- m_typeResolver->containedTypeName(m_returnType)),
- Log_Type, getCurrentBindingSourceLocation());
+ m_logger->log(u"Cannot assign binding of type %1 to %2"_qs.arg(
+ m_typeResolver->containedTypeName(m_state.accumulatorIn),
+ m_typeResolver->containedTypeName(m_returnType)),
+ Log_Type, getCurrentBindingSourceLocation());
return;
}
@@ -358,8 +357,8 @@ void QQmlJSTypePropagator::handleUnqualifiedAccess(const QString &name) const
}
}
- m_logger->logWarning(QLatin1String("Unqualified access"), Log_UnqualifiedAccess, location, true,
- true, suggestion);
+ m_logger->log(QLatin1String("Unqualified access"), Log_UnqualifiedAccess, location, true, true,
+ suggestion);
}
void QQmlJSTypePropagator::checkDeprecated(QQmlJSScope::ConstPtr scope, const QString &name,
@@ -407,7 +406,7 @@ void QQmlJSTypePropagator::checkDeprecated(QQmlJSScope::ConstPtr scope, const QS
if (!deprecation.reason.isEmpty())
message.append(QStringLiteral(" (Reason: %1)").arg(deprecation.reason));
- m_logger->logWarning(message, Log_Deprecation, getCurrentSourceLocation());
+ m_logger->log(message, Log_Deprecation, getCurrentSourceLocation());
}
bool QQmlJSTypePropagator::checkRestricted(const QString &propertyName) const
@@ -427,9 +426,9 @@ bool QQmlJSTypePropagator::checkRestricted(const QString &propertyName) const
}
if (!restrictedKind.isEmpty())
- m_logger->logWarning(u"Type is %1. You cannot access \"%2\" from here."_qs.arg(
- restrictedKind, propertyName),
- Log_Type, getCurrentSourceLocation());
+ m_logger->log(u"Type is %1. You cannot access \"%2\" from here."_qs.arg(restrictedKind,
+ propertyName),
+ Log_Type, getCurrentSourceLocation());
return !restrictedKind.isEmpty();
}
@@ -490,8 +489,8 @@ void QQmlJSTypePropagator::generate_StoreNameSloppy(int nameIndex)
if (!type.isWritable() && !m_function->qmlScope->hasOwnProperty(name)) {
setError(u"Can't assign to read-only property %1"_qs.arg(name));
- m_logger->logWarning(u"Cannot assign to read-only property %1"_qs.arg(name), Log_Property,
- getCurrentSourceLocation());
+ m_logger->log(u"Cannot assign to read-only property %1"_qs.arg(name), Log_Property,
+ getCurrentSourceLocation());
return;
}
@@ -571,7 +570,7 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
{} };
}
- m_logger->logWarning(
+ m_logger->log(
u"Using attached type %1 already initialized in a parent scope."_qs.arg(
m_state.accumulatorIn.scopeType()->internalName()),
Log_AttachedPropertyReuse, getCurrentSourceLocation(), true, true,
@@ -592,12 +591,11 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
return;
}
if (m_state.accumulatorIn.isImportNamespace())
- m_logger->logWarning(u"Type not found in namespace"_qs, Log_Type,
- getCurrentSourceLocation());
+ m_logger->log(u"Type not found in namespace"_qs, Log_Type, getCurrentSourceLocation());
} else if (m_state.accumulatorOut.variant() == QQmlJSRegisterContent::Singleton
&& m_state.accumulatorIn.variant() == QQmlJSRegisterContent::ObjectModulePrefix) {
- m_logger->logWarning(u"Cannot load singleton as property of object"_qs, Log_Type,
- getCurrentSourceLocation());
+ m_logger->log(u"Cannot load singleton as property of object"_qs, Log_Type,
+ getCurrentSourceLocation());
m_state.accumulatorOut = QQmlJSRegisterContent();
}
@@ -629,7 +627,7 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
Q_ASSERT(!errorType.isEmpty());
- m_logger->logWarning(
+ m_logger->log(
u"Type \"%1\" of property \"%2\" not %3. This is likely due to a missing dependency entry or a type not being exposed declaratively."_qs
.arg(property.typeName(), propertyName, errorType),
Log_Type, getCurrentSourceLocation());
@@ -650,7 +648,7 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
}
}
- m_logger->logWarning(
+ m_logger->log(
u"Property \"%1\" not found on type \"%2\""_qs.arg(propertyName).arg(typeName),
Log_Type, getCurrentSourceLocation(), true, true, fixSuggestion);
return;
@@ -669,7 +667,7 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName)
}
if (!m_state.accumulatorOut.property().type()) {
- m_logger->logWarning(
+ m_logger->log(
QString::fromLatin1("Type of property \"%2\" not found").arg(propertyName),
Log_Type, getCurrentSourceLocation());
}
@@ -715,8 +713,8 @@ void QQmlJSTypePropagator::generate_StoreProperty(int nameIndex, int base)
if (!property.isWritable()) {
setError(u"Can't assign to read-only property %1"_qs.arg(propertyName));
- m_logger->logWarning(u"Cannot assign to read-only property %1"_qs.arg(propertyName),
- Log_Property, getCurrentSourceLocation());
+ m_logger->log(u"Cannot assign to read-only property %1"_qs.arg(propertyName), Log_Property,
+ getCurrentSourceLocation());
return;
}
@@ -809,9 +807,9 @@ void QQmlJSTypePropagator::generate_CallProperty(int nameIndex, int base, int ar
}
}
- m_logger->logWarning(u"Property \"%1\" not found on type \"%2\""_qs.arg(
- propertyName, m_typeResolver->containedTypeName(callBase)),
- Log_Type, getCurrentSourceLocation(), true, true, fixSuggestion);
+ m_logger->log(u"Property \"%1\" not found on type \"%2\""_qs.arg(
+ propertyName, m_typeResolver->containedTypeName(callBase)),
+ Log_Type, getCurrentSourceLocation(), true, true, fixSuggestion);
return;
}
diff --git a/src/qmlcompiler/qqmljstyperesolver.cpp b/src/qmlcompiler/qqmljstyperesolver.cpp
index c25dc86d46..ce35b05eeb 100644
--- a/src/qmlcompiler/qqmljstyperesolver.cpp
+++ b/src/qmlcompiler/qqmljstyperesolver.cpp
@@ -138,19 +138,19 @@ void QQmlJSTypeResolver::init(QQmlJSImportVisitor *visitor, QQmlJS::AST::Node *p
// If the property is defined in the same scope where it is set,
// we are in fact allowed to set it, even if it's not writable.
if (!property.isWritable() && !scope->hasOwnProperty(binding.propertyName())) {
- m_logger->logWarning(u"Cannot assign to read-only property %1"_qs
- .arg(binding.propertyName()),
- Log_Type, binding.sourceLocation());
+ m_logger->log(u"Cannot assign to read-only property %1"_qs.arg(
+ binding.propertyName()),
+ Log_Type, binding.sourceLocation());
continue;
}
if (!canConvertFromTo(binding.literalType(), property.type())) {
- m_logger->logWarning(u"Cannot assign binding of type %1 to %2"_qs
- .arg(binding.literalTypeName())
- .arg(property.typeName()),
- Log_Type, binding.sourceLocation());
+ m_logger->log(u"Cannot assign binding of type %1 to %2"_qs
+ .arg(binding.literalTypeName())
+ .arg(property.typeName()),
+ Log_Type, binding.sourceLocation());
} else if (property.type() == m_stringType && isNumeric(binding.literalType())) {
- m_logger->logWarning(u"Cannot assign a numeric constant to a string property"_qs,
- Log_Type, binding.sourceLocation());
+ m_logger->log(u"Cannot assign a numeric constant to a string property"_qs,
+ Log_Type, binding.sourceLocation());
}
}
}
@@ -507,9 +507,9 @@ QQmlJSScope::ConstPtr QQmlJSTypeResolver::genericType(const QQmlJSScope::ConstPt
}
}
- m_logger->logWarning(u"Object type %1 is not derived from QObject or QQmlComponent"_qs.arg(
- type->internalName()),
- Log_Compiler);
+ m_logger->log(u"Object type %1 is not derived from QObject or QQmlComponent"_qs.arg(
+ type->internalName()),
+ Log_Compiler, type->sourceLocation());
// Reference types that are not QObject or QQmlComponent are likely JavaScript objects.
// We don't want to deal with those, but m_jsValueType is the best generic option.
@@ -674,15 +674,14 @@ QQmlJSRegisterContent QQmlJSTypeResolver::scopedType(const QQmlJSScope::ConstPtr
if (const auto attached = type->attachedType()) {
if (!genericType(attached)) {
- m_logger->logWarning(u"Cannot resolve generic base of attached %1"_qs.arg(
- attached->internalName()),
- Log_Compiler);
+ m_logger->log(u"Cannot resolve generic base of attached %1"_qs.arg(
+ attached->internalName()),
+ Log_Compiler, attached->sourceLocation());
return {};
} else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
- m_logger->logWarning(
- u"Cannot retrieve attached object for non-reference type %1"_qs.arg(
- type->internalName()),
- Log_Compiler);
+ m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_qs.arg(
+ type->internalName()),
+ Log_Compiler, type->sourceLocation());
return {};
} else {
// We don't know yet whether we need the attached or the plain object. In direct
@@ -822,15 +821,14 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSScope::ConstPtr
if (QQmlJSScope::ConstPtr attachedBase = typeForName(name)) {
if (QQmlJSScope::ConstPtr attached = attachedBase->attachedType()) {
if (!genericType(attached)) {
- m_logger->logWarning(u"Cannot resolve generic base of attached %1"_qs.arg(
- attached->internalName()),
- Log_Compiler);
+ m_logger->log(u"Cannot resolve generic base of attached %1"_qs.arg(
+ attached->internalName()),
+ Log_Compiler, attached->sourceLocation());
return {};
} else if (type->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
- m_logger->logWarning(
- u"Cannot retrieve attached object for non-reference type %1"_qs.arg(
- type->internalName()),
- Log_Compiler);
+ m_logger->log(u"Cannot retrieve attached object for non-reference type %1"_qs.arg(
+ type->internalName()),
+ Log_Compiler, type->sourceLocation());
return {};
} else {
return QQmlJSRegisterContent::create(storedType(attached), attached,
@@ -896,10 +894,10 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(const QQmlJSRegisterContent
}
if (type.isImportNamespace()) {
if (type.scopeType()->accessSemantics() != QQmlJSScope::AccessSemantics::Reference) {
- m_logger->logWarning(
+ m_logger->log(
u"Cannot use non-reference type %1 as base of namespaced attached type"_qs.arg(
type.scopeType()->internalName()),
- Log_Type);
+ Log_Type, type.scopeType()->sourceLocation());
return {};
}
diff --git a/tests/auto/qml/qmllint/tst_qmllint.cpp b/tests/auto/qml/qmllint/tst_qmllint.cpp
index 2469228dc1..3e1fd3b7d9 100644
--- a/tests/auto/qml/qmllint/tst_qmllint.cpp
+++ b/tests/auto/qml/qmllint/tst_qmllint.cpp
@@ -429,10 +429,11 @@ void TestQmllint::dirtyQmlCode_data()
<< QString("Warning: %1:5:35: Property \"weDontKnowIt\" "
"not found on type \"CustomPalette\"")
<< QString() << QString() << false;
- QTest::newRow("inheritanceCylce") << QStringLiteral("Cycle1.qml")
- << QString("Warning: %1: Cycle2 is part of an inheritance "
- "cycle: Cycle2 -> Cycle3 -> Cycle1 -> Cycle2")
- << QString() << QString() << false;
+ QTest::newRow("inheritanceCycle")
+ << QStringLiteral("Cycle1.qml")
+ << QString("Warning: %1:2:1: Cycle2 is part of an inheritance cycle: Cycle2 -> Cycle3 "
+ "-> Cycle1 -> Cycle2")
+ << QString() << QString() << false;
QTest::newRow("badQmldirImportAndDepend")
<< QStringLiteral("qmldirImportAndDepend/bad.qml")
<< QString("Warning: %1:3:1: Item was not found. Did you add all import paths?")
@@ -1057,7 +1058,7 @@ void TestQmllint::compilerWarnings_data()
QTest::newRow("unknownTypeInRegister")
<< QStringLiteral("unknownTypeInRegister.qml") << false
<< QStringLiteral("Functions without type annotations won't be compiled") << true;
- QTest::newRow("pragmaStrict") << QStringLiteral("pragmaStrict.qml") << true
+ QTest::newRow("pragmaStrict") << QStringLiteral("pragmaStrict.qml") << false
<< QStringLiteral(
"Functions without type annotations won't be compiled")
<< false;
@@ -1332,7 +1333,7 @@ void TestQmllint::settingsFile()
QVERIFY(runQmllint("settings/unqualifiedSilent/unqualified.qml", true, QStringList(), false)
.isEmpty());
QVERIFY(runQmllint("settings/unusedImportWarning/unused.qml", false, QStringList(), false)
- .contains(QStringLiteral("Info: %1:2:1: Unused import at %1:2:1")
+ .contains(QStringLiteral("Warning: %1:2:1: Unused import at %1:2:1")
.arg(testFile("settings/unusedImportWarning/unused.qml"))));
QVERIFY(runQmllint("settings/bare/bare.qml", false, {}, false, false)
.contains(QStringLiteral("Failed to find the following builtins: "
diff --git a/tools/qmlcachegen/qmlcachegen.cpp b/tools/qmlcachegen/qmlcachegen.cpp
index d6869ab05b..918c83e6d6 100644
--- a/tools/qmlcachegen/qmlcachegen.cpp
+++ b/tools/qmlcachegen/qmlcachegen.cpp
@@ -270,19 +270,14 @@ int main(int argc, char **argv)
QQmlJSLogger logger;
// Always trigger the qFatal() on "pragma Strict" violations.
- logger.setCategoryError(Log_Compiler, true);
+ logger.setCategoryLevel(Log_Compiler, QtCriticalMsg);
// By default, we're completely silent,
// as the lcAotCompiler category default is QtFatalMsg
- if (lcAotCompiler().isDebugEnabled())
- logger.setCategoryLevel(Log_Compiler, QtDebugMsg);
- else if (lcAotCompiler().isInfoEnabled())
- logger.setCategoryLevel(Log_Compiler, QtInfoMsg);
- else if (lcAotCompiler().isWarningEnabled())
- logger.setCategoryLevel(Log_Compiler, QtWarningMsg);
- else if (lcAotCompiler().isCriticalEnabled())
- logger.setCategoryLevel(Log_Compiler, QtCriticalMsg);
- else
+ const bool loggingEnabled = lcAotCompiler().isDebugEnabled()
+ || lcAotCompiler().isInfoEnabled() || lcAotCompiler().isWarningEnabled()
+ || lcAotCompiler().isCriticalEnabled();
+ if (!loggingEnabled)
logger.setSilent(true);
QQmlJSAotCompiler cppCodeGen(
@@ -297,9 +292,9 @@ int main(int argc, char **argv)
QList<QQmlJS::DiagnosticMessage> warnings = importer.takeGlobalWarnings();
if (!warnings.isEmpty()) {
- logger.logWarning(QStringLiteral("Type warnings occurred while compiling file:"),
- Log_Import);
- logger.processMessages(warnings, QtWarningMsg, Log_Import);
+ logger.log(QStringLiteral("Type warnings occurred while compiling file:"),
+ Log_Import, QQmlJS::SourceLocation());
+ logger.processMessages(warnings, Log_Import);
}
}
} else if (inputFile.endsWith(QLatin1String(".js")) || inputFile.endsWith(QLatin1String(".mjs"))) {
diff --git a/tools/qmltc/main.cpp b/tools/qmltc/main.cpp
index c2002235cf..4904864e89 100644
--- a/tools/qmltc/main.cpp
+++ b/tools/qmltc/main.cpp
@@ -46,8 +46,8 @@
void setupLogger(QQmlJSLogger &logger) // prepare logger to work with compiler
{
- // TODO: support object bindings and change to setCategoryLevel(QtInfoMsg)
- logger.setCategoryError(Log_Compiler, true);
+ logger.setCategoryLevel(Log_Compiler, QtCriticalMsg);
+ logger.setCategoryIgnored(Log_Compiler, false);
}
int main(int argc, char **argv)
@@ -203,9 +203,9 @@ int main(int argc, char **argv)
QList<QQmlJS::DiagnosticMessage> warnings = importer.takeGlobalWarnings();
if (!warnings.isEmpty()) {
- logger.logWarning(QStringLiteral("Type warnings occurred while compiling file:"),
- Log_Import);
- logger.processMessages(warnings, QtWarningMsg, Log_Import);
+ logger.log(QStringLiteral("Type warnings occurred while compiling file:"), Log_Import,
+ QQmlJS::SourceLocation());
+ logger.processMessages(warnings, Log_Import);
}
# endif
diff --git a/tools/qmltc/prototype/codegenerator.cpp b/tools/qmltc/prototype/codegenerator.cpp
index dab45a22b8..5757f57d82 100644
--- a/tools/qmltc/prototype/codegenerator.cpp
+++ b/tools/qmltc/prototype/codegenerator.cpp
@@ -1887,7 +1887,7 @@ void CodeGenerator::compileUrlMethod()
void CodeGenerator::recordError(const QQmlJS::SourceLocation &location, const QString &message)
{
- m_logger->logCritical(message, Log_Compiler, location);
+ m_logger->log(message, Log_Compiler, location);
}
void CodeGenerator::recordError(const QV4::CompiledData::Location &location, const QString &message)
diff --git a/tools/qmltc/prototype/qml2cppcontext.h b/tools/qmltc/prototype/qml2cppcontext.h
index 56bb5a12db..f80beaebfb 100644
--- a/tools/qmltc/prototype/qml2cppcontext.h
+++ b/tools/qmltc/prototype/qml2cppcontext.h
@@ -52,7 +52,7 @@ struct Qml2CppContext
void recordError(const QQmlJS::SourceLocation &location, const QString &message) const
{
Q_ASSERT(logger);
- logger->logCritical(message, Log_Compiler, location);
+ logger->log(message, Log_Compiler, location);
}
void recordError(const QV4::CompiledData::Location &location, const QString &message) const
diff --git a/tools/qmltc/prototype/visitor.cpp b/tools/qmltc/prototype/visitor.cpp
index 307cb992ea..190b2a59a4 100644
--- a/tools/qmltc/prototype/visitor.cpp
+++ b/tools/qmltc/prototype/visitor.cpp
@@ -42,8 +42,8 @@ bool Visitor::visit(QQmlJS::AST::UiInlineComponent *component)
{
if (!QQmlJSImportVisitor::visit(component))
return false;
- m_logger->logCritical(u"Inline components are not supported"_qs, Log_Compiler,
- component->firstSourceLocation());
+ m_logger->log(u"Inline components are not supported"_qs, Log_Compiler,
+ component->firstSourceLocation());
// despite the failure, return true here so that we do not assert in
// QQmlJSImportVisitor::endVisit(UiInlineComponent)
return true;
diff --git a/tools/qmltc/qmltccompiler.cpp b/tools/qmltc/qmltccompiler.cpp
index 6510a6d51d..6afa656c27 100644
--- a/tools/qmltc/qmltccompiler.cpp
+++ b/tools/qmltc/qmltccompiler.cpp
@@ -486,8 +486,8 @@ void QmltcCompiler::compileBinding(QmltcType &current, const QQmlJSMetaPropertyB
break;
}
default: {
- m_logger->logWarning(u"Binding type is not supported (yet)"_qs, Log_Compiler,
- binding.sourceLocation());
+ m_logger->log(u"Binding type is not supported (yet)"_qs, Log_Compiler,
+ binding.sourceLocation());
break;
}
}
diff --git a/tools/qmltc/qmltccompiler.h b/tools/qmltc/qmltccompiler.h
index 0574b03088..95b60ec9e4 100644
--- a/tools/qmltc/qmltccompiler.h
+++ b/tools/qmltc/qmltccompiler.h
@@ -97,7 +97,7 @@ private:
{
// pretty much any compiler error is a critical error (we cannot
// generate code - compilation fails)
- m_logger->logCritical(message, category, location);
+ m_logger->log(message, category, location);
}
void recordError(const QV4::CompiledData::Location &location, const QString &message,
QQmlJSLoggerCategory category = Log_Compiler)
diff --git a/tools/qmltc/qmltcvisitor.cpp b/tools/qmltc/qmltcvisitor.cpp
index 691496d7c7..375a18fc5b 100644
--- a/tools/qmltc/qmltcvisitor.cpp
+++ b/tools/qmltc/qmltcvisitor.cpp
@@ -200,15 +200,14 @@ bool QmltcVisitor::visit(QQmlJS::AST::UiPublicMember *publicMember)
if (methods.size() != 1) {
const QString errorString =
methods.isEmpty() ? u"no signal"_qs : u"too many signals"_qs;
- m_logger->logCritical(
+ m_logger->log(
u"internal error: %1 found for property '%2'"_qs.arg(errorString, name),
Log_Compiler, publicMember->identifierToken);
return false;
} else if (methods[0].methodType() != QQmlJSMetaMethod::Signal) {
- m_logger->logCritical(
- u"internal error: method %1 of property %2 must be a signal"_qs.arg(
- prop.notify(), name),
- Log_Compiler, publicMember->identifierToken);
+ m_logger->log(u"internal error: method %1 of property %2 must be a signal"_qs.arg(
+ prop.notify(), name),
+ Log_Compiler, publicMember->identifierToken);
return false;
}
}