diff options
author | Maximilian Goldstein <max.goldstein@qt.io> | 2021-07-13 11:58:26 +0200 |
---|---|---|
committer | Maximilian Goldstein <max.goldstein@qt.io> | 2021-07-14 15:10:45 +0200 |
commit | 5b1a3d50e618bb0ee9a7a095d65b24f26b633b00 (patch) | |
tree | 93f8b0e50d29bff955a59438b396b79910cf337a | |
parent | 7ca78c28eb1440a1b4b7c1830bea024ba69e32bb (diff) |
qv4codegen: Provide more accurate SourceLocations
Previously the source locations in the bytecodegenerator were often imprecise due to them not being updated often enough.
This change makes sure that FieldMemberExpressions and IdentifierExpressions report more accurate locations instead.
Change-Id: Ib53cda5cc927551c25ed32ed34d4b65d82f5e199
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/qml/compiler/qv4codegen.cpp | 21 | ||||
-rw-r--r-- | src/qml/compiler/qv4codegen_p.h | 11 | ||||
-rw-r--r-- | tests/auto/qml/qqmlqt/tst_qqmlqt.cpp | 7 |
3 files changed, 29 insertions, 10 deletions
diff --git a/src/qml/compiler/qv4codegen.cpp b/src/qml/compiler/qv4codegen.cpp index 7787f1541a..2b4168e155 100644 --- a/src/qml/compiler/qv4codegen.cpp +++ b/src/qml/compiler/qv4codegen.cpp @@ -1293,7 +1293,9 @@ bool Codegen::visit(ArrayMemberExpression *ast) if (arrayIndex == UINT_MAX) { auto jumpLabel = ast->isOptional ? m_optionalChainLabels.take(ast) : Moth::BytecodeGenerator::Label(); - setExprResult(Reference::fromMember(base, str->value.toString(), jumpLabel, targetLabel)); + setExprResult(Reference::fromMember(base, str->value.toString(), + ast->expression->firstSourceLocation(), jumpLabel, + targetLabel)); return false; } @@ -2489,9 +2491,10 @@ bool Codegen::visit(FieldMemberExpression *ast) return false; } - setExprResult(Reference::fromMember(base, ast->name.toString(), - ast->isOptional ? m_optionalChainLabels.take(ast) : Moth::BytecodeGenerator::Label(), - label.has_value() ? label.value() : Moth::BytecodeGenerator::Label())); + setExprResult(Reference::fromMember( + base, ast->name.toString(), ast->firstSourceLocation(), + ast->isOptional ? m_optionalChainLabels.take(ast) : Moth::BytecodeGenerator::Label(), + label.has_value() ? label.value() : Moth::BytecodeGenerator::Label())); return false; } @@ -2625,12 +2628,14 @@ Codegen::Reference Codegen::referenceForName(const QString &name, bool isLhs, co r.isReferenceToConst = resolved.isConst; r.requiresTDZCheck = resolved.requiresTDZCheck; r.name = name; // used to show correct name at run-time when TDZ check fails. + r.sourceLocation = accessLocation; return r; } Reference r = Reference::fromName(this, name); r.global = useFastLookups && (resolved.type == Context::ResolvedName::Global || resolved.type == Context::ResolvedName::QmlGlobal); r.qmlGlobal = resolved.type == Context::ResolvedName::QmlGlobal; + r.sourceLocation = accessLocation; if (!r.global && !r.qmlGlobal && m_globalNames.contains(name)) r.global = true; return r; @@ -4640,6 +4645,10 @@ QT_WARNING_POP return; } } + + if (sourceLocation.isValid()) + codegen->bytecodeGenerator->setLocation(sourceLocation); + if (!disable_lookups && global) { if (qmlGlobal) { Instruction::LoadQmlContextPropertyLookup load; @@ -4659,6 +4668,10 @@ QT_WARNING_POP case Member: propertyBase.loadInAccumulator(); tdzCheck(requiresTDZCheck); + + if (sourceLocation.isValid()) + codegen->bytecodeGenerator->setLocation(sourceLocation); + if (!disable_lookups && codegen->useFastLookups) { if (optionalChainJumpLabel->isValid()) { // If we got a valid jump label, this means it's an optional lookup auto jump = codegen->bytecodeGenerator->jumpOptionalLookup(codegen->registerGetterLookup(propertyNameIndex)); diff --git a/src/qml/compiler/qv4codegen_p.h b/src/qml/compiler/qv4codegen_p.h index f4a7bf4465..58f46f9313 100644 --- a/src/qml/compiler/qv4codegen_p.h +++ b/src/qml/compiler/qv4codegen_p.h @@ -279,14 +279,18 @@ public: r.name = name; return r; } - static Reference fromMember(const Reference &baseRef, const QString &name, - Moth::BytecodeGenerator::Label jumpLabel = Moth::BytecodeGenerator::Label(), - Moth::BytecodeGenerator::Label targetLabel = Moth::BytecodeGenerator::Label()) { + static Reference + fromMember(const Reference &baseRef, const QString &name, + QQmlJS::SourceLocation sourceLocation = QQmlJS::SourceLocation(), + Moth::BytecodeGenerator::Label jumpLabel = Moth::BytecodeGenerator::Label(), + Moth::BytecodeGenerator::Label targetLabel = Moth::BytecodeGenerator::Label()) + { Q_ASSERT(baseRef.isValid()); Reference r(baseRef.codegen, Member); r.propertyBase = baseRef.asRValue(); r.propertyNameIndex = r.codegen->registerString(name); r.requiresTDZCheck = baseRef.requiresTDZCheck; + r.sourceLocation = sourceLocation; r.optionalChainJumpLabel.reset(new Moth::BytecodeGenerator::Label(jumpLabel)); r.optionalChainTargetLabel.reset(new Moth::BytecodeGenerator::Label(targetLabel)); return r; @@ -382,6 +386,7 @@ public: quint32 isVolatile:1; quint32 global:1; quint32 qmlGlobal:1; + QQmlJS::SourceLocation sourceLocation = QQmlJS::SourceLocation(); QSharedPointer<Moth::BytecodeGenerator::Label> optionalChainJumpLabel; QSharedPointer<Moth::BytecodeGenerator::Label> optionalChainTargetLabel; diff --git a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp index 62e42072b0..f7148f9318 100644 --- a/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp +++ b/tests/auto/qml/qqmlqt/tst_qqmlqt.cpp @@ -929,9 +929,10 @@ void tst_qqmlqt::dateTimeFormattingVariants() if (variant.typeId() == QMetaType::QColor || variant.typeId() == QMetaType::Int) { if (method == "formatTime") { // formatTime has special error handling as it parses the strings itself. - QTest::ignoreMessage(QtWarningMsg, QRegularExpression( - "formatting.qml:18: Error: Invalid argument passed to " - "formatTime")); + QTest::ignoreMessage( + QtWarningMsg, + QRegularExpression("formatting.qml:19: Error: Invalid argument passed to " + "formatTime")); } else { QTest::ignoreMessage(QtWarningMsg, QRegularExpression("Could not convert argument 0 at")); |