diff options
| author | Olivier De Cannière <olivier.decanniere@qt.io> | 2024-08-02 10:13:44 +0200 |
|---|---|---|
| committer | Olivier De Cannière <olivier.decanniere@qt.io> | 2024-08-21 19:57:58 +0200 |
| commit | d70abd83dc94d722cde6d4b19b9d35c5f4f19946 (patch) | |
| tree | 1119f20b6f64d71b4602e7d4e39f7dc0c2caeec4 /src/qmlcompiler/qqmljslintercodegen.cpp | |
| parent | 06577c9e80eb150b6b9e76e7805bfed1abbae82d (diff) | |
Compiler: Create infrastructure to support multiple warnings
Currently only one DiagnosticMessage can be stored at a time when using
the compiler. However, we want to be able to show more than one to the
user.
Therefore, use a list that gets passed inside the compiler instead of a
pointer to the sole error.
This also means that the error is valid by its very existence. There is
no need to check validity explicitly anymore.
Task-number: QTBUG-127624
Change-Id: I356db917b86703b508dc1ad52de7825d82eafd71
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Reviewed-by: Sami Shalayel <sami.shalayel@qt.io>
Diffstat (limited to 'src/qmlcompiler/qqmljslintercodegen.cpp')
| -rw-r--r-- | src/qmlcompiler/qqmljslintercodegen.cpp | 84 |
1 files changed, 46 insertions, 38 deletions
diff --git a/src/qmlcompiler/qqmljslintercodegen.cpp b/src/qmlcompiler/qqmljslintercodegen.cpp index 314c2087e4..e33fe7139b 100644 --- a/src/qmlcompiler/qqmljslintercodegen.cpp +++ b/src/qmlcompiler/qqmljslintercodegen.cpp @@ -30,50 +30,56 @@ void QQmlJSLinterCodegen::setDocument(const QmlIR::JSCodeGen *codegen, m_unitGenerator = &document->jsGenerator; } -std::variant<QQmlJSAotFunction, QQmlJS::DiagnosticMessage> +std::variant<QQmlJSAotFunction, QList<QQmlJS::DiagnosticMessage>> QQmlJSLinterCodegen::compileBinding(const QV4::Compiler::Context *context, const QmlIR::Binding &irBinding, QQmlJS::AST::Node *astNode) { QQmlJSFunctionInitializer initializer( &m_typeResolver, m_currentObject->location, m_currentScope->location); - QQmlJS::DiagnosticMessage initializationError; + QList<QQmlJS::DiagnosticMessage> initializationErrors; const QString name = m_document->stringAt(irBinding.propertyNameIndex); QQmlJSCompilePass::Function function = - initializer.run(context, name, astNode, irBinding, &initializationError); - if (initializationError.isValid()) - diagnose(initializationError.message, initializationError.type, initializationError.loc); + initializer.run(context, name, astNode, irBinding, &initializationErrors); + for (const auto &error : initializationErrors) + diagnose(error.message, error.type, error.loc); - QQmlJS::DiagnosticMessage analyzeError; - if (!analyzeFunction(context, &function, &analyzeError)) { + QList<QQmlJS::DiagnosticMessage> analyzeErrors; + if (!analyzeFunction(context, &function, &analyzeErrors)) { // If it's a signal and the function just returns a closure, it's harmless. // Otherwise promote the message to warning level. - return diagnose(u"Could not compile binding for %1: %2"_s.arg(name, analyzeError.message), - (function.isSignalHandler && analyzeError.type == QtDebugMsg) - ? QtDebugMsg - : QtWarningMsg, - analyzeError.loc); + for (auto &error : analyzeErrors) { + error = diagnose(u"Could not compile binding for %1: %2"_s.arg(name, error.message), + (function.isSignalHandler && error.type == QtDebugMsg) + ? QtDebugMsg + : QtWarningMsg, + error.loc); + } + return analyzeErrors; } return QQmlJSAotFunction {}; } -std::variant<QQmlJSAotFunction, QQmlJS::DiagnosticMessage> +std::variant<QQmlJSAotFunction, QList<QQmlJS::DiagnosticMessage>> QQmlJSLinterCodegen::compileFunction(const QV4::Compiler::Context *context, const QString &name, QQmlJS::AST::Node *astNode) { - QQmlJS::DiagnosticMessage initializationError; + QList<QQmlJS::DiagnosticMessage> initializationErrors; QQmlJSFunctionInitializer initializer( &m_typeResolver, m_currentObject->location, m_currentScope->location); QQmlJSCompilePass::Function function = - initializer.run(context, name, astNode, &initializationError); - if (initializationError.isValid()) - diagnose(initializationError.message, initializationError.type, initializationError.loc); - - QQmlJS::DiagnosticMessage analyzeError; - if (!analyzeFunction(context, &function, &analyzeError)) { - return diagnose(u"Could not compile function %1: %2"_s.arg(name, analyzeError.message), - QtWarningMsg, analyzeError.loc); + initializer.run(context, name, astNode, &initializationErrors); + for (const auto &error : initializationErrors) + diagnose(error.message, error.type, error.loc); + + QList<QQmlJS::DiagnosticMessage> analyzeErrors; + if (!analyzeFunction(context, &function, &analyzeErrors)) { + for (auto &error : analyzeErrors) { + error = diagnose(u"Could not compile function %1: %2"_s.arg(name, error.message), + QtWarningMsg, error.loc); + } + return analyzeErrors; } return QQmlJSAotFunction {}; @@ -88,31 +94,33 @@ void QQmlJSLinterCodegen::setPassManager(QQmlSA::PassManager *passManager) bool QQmlJSLinterCodegen::analyzeFunction(const QV4::Compiler::Context *context, QQmlJSCompilePass::Function *function, - QQmlJS::DiagnosticMessage *error) + QList<QQmlJS::DiagnosticMessage> *errors) { - QQmlJSTypePropagator propagator(m_unitGenerator, &m_typeResolver, m_logger, - {}, {}, m_passManager); - auto [basicBlocks, annotations] = propagator.run(function, error); - if (!error->isValid()) { - QQmlJSShadowCheck shadowCheck(m_unitGenerator, &m_typeResolver, m_logger, basicBlocks, - annotations); - shadowCheck.run(function, error); + QQmlJSTypePropagator propagator(m_unitGenerator, &m_typeResolver, m_logger, errors, {}, {}, + m_passManager); + auto [basicBlocks, annotations] = propagator.run(function); + if (errors->isEmpty()) { + QQmlJSShadowCheck shadowCheck(m_unitGenerator, &m_typeResolver, m_logger, errors, + basicBlocks, annotations); + shadowCheck.run(function); } - if (!error->isValid()) { - QQmlJSStorageInitializer initializer(m_unitGenerator, &m_typeResolver, m_logger, + if (errors->isEmpty()) { + QQmlJSStorageInitializer initializer(m_unitGenerator, &m_typeResolver, m_logger, errors, basicBlocks, annotations); - initializer.run(function, error); + initializer.run(function); } - if (!error->isValid()) { - QQmlJSStorageGeneralizer generalizer(m_unitGenerator, &m_typeResolver, m_logger, + if (errors->isEmpty()) { + QQmlJSStorageGeneralizer generalizer(m_unitGenerator, &m_typeResolver, m_logger, errors, basicBlocks, annotations); - generalizer.run(function, error); + generalizer.run(function); } - if (error->isValid()) { - error->type = context->returnsClosure ? QtDebugMsg : QtWarningMsg; + if (!errors->isEmpty()) { + QtMsgType type = context->returnsClosure ? QtDebugMsg : QtWarningMsg; + for (auto &error : *errors) + error.type = type; return false; } |
