10#include <private/qv4compilerscanfunctions_p.h>
12#include <QtQmlCompiler/private/qqmlsasourcelocation_p.h>
33 m_passManager(passManager)
46 if (m_state.needsMorePasses)
49 m_prevStateAnnotations = m_state.annotations;
50 m_state = PassState();
59 }
while (m_state.needsMorePasses);
61 return m_state.annotations;
64#define INSTR_PROLOGUE_NOT_IMPLEMENTED() \
65 setError(u"Instruction \"%1\" not implemented"_s.arg(QString::fromUtf8(__func__))); \
68#define INSTR_PROLOGUE_NOT_IMPLEMENTED_IGNORE() \
69 m_logger->log(u"Instruction \"%1\" not implemented"_s.arg(QString::fromUtf8(__func__)), \
70 qmlCompiler, QQmlJS::SourceLocation()); \
76 m_passManager->d_func()->analyzeBinding(
81 getCurrentBindingSourceLocation()));
86 }
else if (!m_returnType.
isValid() && m_state.accumulatorIn().isValid()
89 setError(u
"function without return type annotation returns %1"_s
90 .
arg(m_state.accumulatorIn().descriptiveName()));
94 m_logger->
log(u
"Function without return type annotation returns %1"_s.arg(
99 }
else if (!canConvertFromTo(m_state.accumulatorIn(), m_returnType)) {
100 setError(u
"cannot convert from %1 to %2"_s
101 .
arg(m_state.accumulatorIn().descriptiveName(),
104 m_logger->
log(u
"Cannot assign binding of type %1 to %2"_s.arg(
114 addReadAccumulator(m_state.accumulatorIn());
116 addReadAccumulator(m_returnType);
119 m_state.setHasSideEffects(
true);
120 m_state.skipInstructionsUntilNextJumpTarget =
true;
173 m_state.setIsRename(
true);
175 m_state.addReadRegister(reg, content);
182 m_state.setIsRename(
true);
183 m_state.addReadAccumulator(m_state.accumulatorIn());
184 m_state.setRegister(reg, m_state.accumulatorIn());
191 m_state.setIsRename(
true);
193 m_state.addReadRegister(srcReg, content);
194 m_state.setRegister(destReg, content);
255 if (!m_state.accumulatorOut().isValid())
283 return combine(entries.constFirst().location, entries.constLast().location);
286void QQmlJSTypePropagator::handleUnqualifiedAccess(
const QString &
name,
bool isMethod)
const
288 auto location = getCurrentSourceLocation();
304 std::optional<QQmlJSFixSuggestion> suggestion;
308 auto &scope = childScopes[
i];
309 if (
location.offset > scope->sourceLocation().offset) {
310 if (
i + 1 < childScopes.size()
311 && childScopes.at(
i + 1)->sourceLocation().offset <
location.offset)
313 if (scope->childScopes().size() == 0)
316 const auto jsId = scope->childScopes().first()->findJSIdentifier(
name);
327 QString fixString = handler.isMultiline ? u
"function("_s : u
"("_s;
328 const auto parameters = handler.signalParameters;
329 for (
int numParams = parameters.size(); numParams > 0; --numParams) {
330 fixString += parameters.
at(parameters.size() - numParams);
332 fixString += u
", "_s;
335 fixString += handler.isMultiline ? u
") "_s : u
") => "_s;
338 name + u
" is accessible in this scope because you are handling a signal"
339 " at %1:%2. Use a function instead.\n"_s
345 suggestion->setAutoApplicable();
355 if (
name == u
"model" ||
name == u
"index") {
357 const auto bindings =
parent->ownPropertyBindings(u
"delegate"_s);
359 for (
auto it = bindings.first;
it != bindings.second;
it++) {
360 if (!
it->hasObject())
364 name +
" is implicitly injected into this delegate."
365 " Add a required property instead."_L1,
375 if (!suggestion.has_value()) {
377 scope = scope->parentScope()) {
378 if (scope->hasProperty(
name)) {
384 name +
" is a member of a parent element.\n You can qualify the access "
385 "with its id to avoid this warning:\n"_L1,
387 (
id.isEmpty() ? u
"<id>."_s : (
id + u
'.'))
391 suggestion->setHint(
"You first have to give the element an id"_L1);
393 suggestion->setAutoApplicable();
400 const QLatin1String replacement =
"pragma ComponentBehavior: Bound"_L1;
402 "Set \"%1\" in order to use IDs from outer components in nested components."_L1
405 replacement +
'\n'_L1
407 bindComponents.setAutoApplicable();
408 suggestion = bindComponents;
411 if (!suggestion.has_value()) {
412 if (
auto didYouMean =
417 didYouMean.has_value()) {
418 suggestion = didYouMean;
431 if (qmlScope.isNull())
443 annotations =
method.annotations();
448 annotations =
property.annotations();
451 auto deprecationAnn = std::find_if(
453 [](
const QQmlJSAnnotation &annotation) { return annotation.isDeprecation(); });
455 if (deprecationAnn == annotations.
constEnd())
462 descriptor += u
'(' +
method.parameterNames().join(u
", "_s) + u
')';
465 .arg(isMethod ? u
"Method"_s : u
"Property"_s)
475QQmlJSTypePropagator::PropertyResolution QQmlJSTypePropagator::propertyResolution(
478 auto property = scope->
property(propertyName);
480 return PropertyMissing;
484 errorType = u
"found"_s;
485 else if (!
property.type()->isFullyResolved())
486 errorType = u
"fully resolved"_s;
488 return PropertyFullyResolved;
493 u
"Type \"%1\" of property \"%2\" not %3. This is likely due to a missing dependency entry or a type not being exposed declaratively."_s
494 .
arg(
property.typeName(), propertyName, errorType),
497 return PropertyTypeUnresolved;
506 QString propertyType = u
"Property"_s;
512 errorType = u
"shadowed by a property."_s;
513 switch (
methods.first().methodType()) {
514 case QQmlJSMetaMethodType::Signal:
515 propertyType = u
"Signal"_s;
517 case QQmlJSMetaMethodType::Slot:
518 propertyType = u
"Slot"_s;
520 case QQmlJSMetaMethodType::Method:
521 propertyType = u
"Method"_s;
528 u
"a variant property. It may or may not be a method. Use a regular function instead."_s;
531 u
"a QJSValue property. It may or may not be a method. Use a regular Q_INVOKABLE instead."_s;
533 errorType = u
"not a method"_s;
537 getCurrentSourceLocation(),
true,
true, {});
562 if (!m_state.accumulatorOut().isValid()) {
564 handleUnqualifiedAccess(
name,
false);
574 setError(u
"Cannot determine generic type for "_s +
name);
580 setError(u
"Cannot retrieve a non-object type by ID: "_s +
name);
584 if (m_passManager !=
nullptr) {
585 m_passManager->d_func()->analyzeRead(
589 getCurrentBindingSourceLocation()));
613 if (!
type.isValid()) {
614 handleUnqualifiedAccess(
name,
false);
619 if (!
type.isProperty()) {
621 : u
"Cannot assign to non-property %1"_s;
625 getCurrentSourceLocation());
631 setError(u
"Can't assign to read-only property %1"_s.arg(
name));
634 getCurrentSourceLocation());
639 if (!canConvertFromTo(
in,
type)) {
640 setError(u
"cannot convert from %1 to %2"_s
641 .
arg(
in.descriptiveName(),
type.descriptiveName()));
644 if (m_passManager !=
nullptr) {
645 m_passManager->d_func()->analyzeWrite(
650 getCurrentBindingSourceLocation()));
653 m_state.setHasSideEffects(
true);
656 if (
type.property().reset().isEmpty())
657 setError(u
"Cannot assign potential undefined to %1"_s.arg(
type.descriptiveName()));
661 addReadAccumulator(
in);
663 addReadAccumulator(
type);
680 if (
base.isEnumeration()) {
681 const auto metaEn =
base.enumeration();
682 if (!metaEn.isScoped()) {
683 m_logger->
log(u
"You cannot access unscoped enum \"%1\" from here."_s.arg(propertyName),
686 }
else if (!metaEn.hasKey(propertyName)) {
688 getCurrentSourceLocation());
689 m_logger->
log(u
"\"%1\" is not an entry of enum \"%2\"."_s.arg(propertyName)
703 if ((!baseRegister.
isList()
707 addReadAccumulator(jsValue);
708 addReadRegister(
base, jsValue);
709 setAccumulator(jsValue);
721 addReadRegister(
base, baseRegister);
733 if (!baseRegister.
isList()
736 addReadAccumulator(jsValue);
737 addReadRegister(
base, jsValue);
738 addReadRegister(
index, jsValue);
742 m_state.setHasSideEffects(
true);
754 addReadRegister(
base, baseRegister);
762 m_state.setHasSideEffects(
true);
765void QQmlJSTypePropagator::propagatePropertyLookup(
const QString &propertyName)
769 m_state.accumulatorIn(),
770 m_state.accumulatorIn().isImportNamespace()
772 + u
'.' + propertyName
775 if (!m_state.accumulatorOut().isValid()) {
777 Q_ASSERT(m_state.accumulatorIn().isValid());
778 addReadAccumulator(m_state.accumulatorIn());
780 m_state.accumulatorIn().storedType(),
786 if (m_state.accumulatorIn().isImportNamespace())
788 getCurrentSourceLocation());
792 u
"Cannot access singleton as a property of an object. Did you want to access an attached object?"_s,
800 if (!m_state.accumulatorOut().isValid()) {
801 setError(u
"Cannot load property %1 from %2."_s
802 .
arg(propertyName, m_state.accumulatorIn().descriptiveName()));
808 if (m_state.accumulatorIn().isList() && propertyName == u
"length")
814 if (propertyResolution(baseType, propertyName) != PropertyMissing)
817 std::optional<QQmlJSFixSuggestion> fixSuggestion;
820 getCurrentSourceLocation());
821 suggestion.has_value()) {
822 fixSuggestion = suggestion;
825 if (!fixSuggestion.has_value()
829 m_state.accumulatorIn().scopeType()->enumerations())
830 enumKeys << metaEnum.
keys();
832 if (
auto suggestion =
834 suggestion.has_value()) {
835 fixSuggestion = suggestion;
844 if (m_state.accumulatorOut().isMethod() && m_state.accumulatorOut().method().size() != 1) {
845 setError(u
"Cannot determine overloaded method on loadProperty"_s);
849 if (m_state.accumulatorOut().isProperty()) {
852 setError(u
"Type %1 does not have a property %2 for reading"_s
853 .
arg(m_state.accumulatorIn().descriptiveName(), propertyName));
857 if (!m_state.accumulatorOut().property().type()) {
864 if (m_passManager !=
nullptr) {
865 const bool isAttached =
868 m_passManager->d_func()->analyzeRead(
874 QQmlSA::SourceLocationPrivate::createQQmlSASourceLocation(
875 getCurrentBindingSourceLocation()));
881 switch (m_state.accumulatorOut().variant()) {
887 if (m_state.accumulatorIn().isImportNamespace())
888 addReadAccumulator(m_state.accumulatorIn());
891 addReadAccumulator(m_state.accumulatorIn());
922 auto callBase = m_state.registers[
base].content;
927 setError(u
"Type %1 does not have a property %2 for writing"_s
928 .
arg(callBase.descriptiveName(), propertyName));
933 setError(u
"Can't assign to read-only property %1"_s.arg(propertyName));
935 m_logger->
log(u
"Cannot assign to read-only property %1"_s.arg(propertyName),
941 if (!canConvertFromTo(m_state.accumulatorIn(),
property)) {
942 setError(u
"cannot convert from %1 to %2"_s
943 .
arg(m_state.accumulatorIn().descriptiveName(),
property.descriptiveName()));
947 if (m_passManager !=
nullptr) {
950 m_passManager->d_func()->analyzeWrite(
958 getCurrentBindingSourceLocation()));
961 m_state.setHasSideEffects(
true);
963 addReadRegister(
base, callBase);
1000 m_state.setHasSideEffects(
true);
1009 m_state.setHasSideEffects(
true);
1019 return consoleMethod == u
"log" || consoleMethod == u
"debug" || consoleMethod == u
"info"
1020 || consoleMethod == u
"warn" || consoleMethod == u
"error";
1026 const auto callBase = m_state.registers[
base].content;
1040 for (
int i = 0;
i < argc; ++
i)
1041 addReadRegister(argv +
i, realType);
1042 setAccumulator(realType);
1054 addReadRegister(
base, voidType);
1068 addReadRegister(argv, stringType);
1072 for (
int i = 1;
i < argc; ++
i)
1073 addReadRegister(argv +
i, stringType);
1075 m_state.setHasSideEffects(
true);
1076 setAccumulator(voidType);
1083 addReadRegister(
base, jsValueType);
1084 for (
int i = 0;
i < argc; ++
i)
1085 addReadRegister(argv +
i, jsValueType);
1086 setAccumulator(jsValueType);
1087 m_state.setHasSideEffects(
true);
1093 if (!member.isMethod()) {
1094 setError(u
"Type %1 does not have a property %2 for calling"_s
1095 .
arg(callBase.descriptiveName(), propertyName));
1097 if (callBase.isType() && isCallingProperty(callBase.type(), propertyName))
1103 std::optional<QQmlJSFixSuggestion> fixSuggestion;
1106 getCurrentSourceLocation());
1107 suggestion.has_value()) {
1108 fixSuggestion = suggestion;
1111 m_logger->
log(u
"Member \"%1\" not found on type \"%2\""_s.arg(
1117 checkDeprecated(baseType, propertyName,
true);
1119 if (m_passManager !=
nullptr) {
1121 m_passManager->d_func()->analyzeRead(
1125 getCurrentBindingSourceLocation()));
1128 addReadRegister(
base, callBase);
1131 if (propertyName == u
"arg"_s && argc == 1) {
1132 propagateStringArgCall(argv);
1137 if (baseType->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence
1139 && propagateArrayMethod(propertyName, argc, argv, callBase)) {
1143 propagateCall(member.method(), argc, argv, member.scopeType());
1154 if (
method.isJavaScriptFunction() && !javascriptFunction.
isValid())
1155 javascriptFunction =
method;
1157 if (
method.returnType().isNull() && !
method.returnTypeName().isEmpty()) {
1158 errors->append(u
"return type %1 cannot be resolved"_s
1166 u
"Function expects %1 arguments, but %2 were provided"_s.arg(
arguments.
size())
1171 bool fuzzyMatch =
true;
1172 bool exactMatch =
true;
1173 for (
int i = 0;
i < argc; ++
i) {
1177 u
"type %1 for argument %2 cannot be resolved"_s.arg(
arguments[
i].typeName())
1184 const auto content = m_state.registers[argv +
i].content;
1193 u
"argument %1 contains %2 but is expected to contain the type %3"_s.arg(
i).arg(
1194 m_state.registers[argv +
i].content.descriptiveName(),
1202 else if (fuzzyMatch && !candidate.
isValid())
1206 return candidate.
isValid() ? candidate : javascriptFunction;
1218 if (
it != m_prevStateAnnotations.
end()) {
1221 m_state.setRegister(
index, lastTry);
1229void QQmlJSTypePropagator::mergeRegister(
1239 if (
it == m_prevStateAnnotations.
end())
1242 auto conversion =
it->second.typeConversions.
find(
index);
1243 if (conversion ==
it->second.typeConversions.
end())
1246 const VirtualRegister &lastTry = conversion.value();
1248 Q_ASSERT(lastTry.content.isValid());
1249 Q_ASSERT(lastTry.content.isConversion());
1252 || lastTry.content.conversionOrigins() != merged.conversionOrigins()) {
1258 m_state.registers[
index] = lastTry;
1262 if (!tryPrevStateConversion(
index, merged)) {
1266 m_state.registers[
index].content = merged;
1273 (m_state.registers[
index].content, convertTo));
1276void QQmlJSTypePropagator::propagateCall(
1283 if (!
match.isValid()) {
1288 setError(u
"No matching override found. Candidates:\n"_s + errors.join(u
'\n'));
1292 const auto returnType =
match.isJavaScriptFunction()
1297 match.isJavaScriptFunction()
1301 if (!m_state.accumulatorOut().isValid())
1302 setError(u
"Cannot store return type of method %1()."_s.arg(
match.methodName()));
1304 m_state.setHasSideEffects(
true);
1306 for (
int i = 0;
i < argc; ++
i) {
1311 if (!
type.isNull()) {
1320bool QQmlJSTypePropagator::propagateTranslationMethod(
1336 if (
method.methodName() == u
"qsTranslate"_s) {
1339 addReadRegister(argv + 3, intType);
1342 addReadRegister(argv + 2, stringType);
1345 addReadRegister(argv + 1, stringType);
1346 addReadRegister(argv, stringType);
1347 setAccumulator(returnType);
1354 if (
method.methodName() == u
"QT_TRANSLATE_NOOP"_s) {
1357 addReadRegister(argv + 2, stringType);
1360 addReadRegister(argv + 1, stringType);
1361 addReadRegister(argv, stringType);
1362 setAccumulator(returnType);
1369 if (
method.methodName() == u
"qsTr"_s) {
1372 addReadRegister(argv + 2, intType);
1375 addReadRegister(argv + 1, stringType);
1378 addReadRegister(argv, stringType);
1379 setAccumulator(returnType);
1386 if (
method.methodName() == u
"QT_TR_NOOP"_s) {
1389 addReadRegister(argv + 1, stringType);
1392 addReadRegister(argv, stringType);
1393 setAccumulator(returnType);
1400 if (
method.methodName() == u
"qsTrId"_s) {
1403 addReadRegister(argv + 1, intType);
1406 addReadRegister(argv, stringType);
1407 setAccumulator(returnType);
1414 if (
method.methodName() == u
"QT_TRID_NOOP"_s) {
1417 addReadRegister(argv, stringType);
1418 setAccumulator(returnType);
1428void QQmlJSTypePropagator::propagateStringArgCall(
int argv)
1433 Q_ASSERT(m_state.accumulatorOut().isValid());
1436 m_state.registers[argv].content);
1461bool QQmlJSTypePropagator::propagateArrayMethod(
1484 if (
name == u
"copyWithin" && argc > 0 && argc < 4) {
1485 for (
int i = 0;
i < argc; ++
i) {
1486 if (!canConvertFromTo(m_state.registers[argv +
i].content, intType))
1490 for (
int i = 0;
i < argc; ++
i)
1491 addReadRegister(argv +
i, intType);
1493 setAccumulator(baseType);
1494 m_state.setHasSideEffects(canHaveSideEffects);
1498 if (
name == u
"fill" && argc > 0 && argc < 4) {
1499 if (!canConvertFromTo(m_state.registers[argv].content, valueType))
1502 for (
int i = 1;
i < argc; ++
i) {
1503 if (!canConvertFromTo(m_state.registers[argv +
i].content, intType))
1507 addReadRegister(argv, valueType);
1509 for (
int i = 1;
i < argc; ++
i)
1510 addReadRegister(argv +
i, intType);
1512 setAccumulator(baseType);
1513 m_state.setHasSideEffects(canHaveSideEffects);
1517 if (
name == u
"includes" && argc > 0 && argc < 3) {
1518 if (!canConvertFromTo(m_state.registers[argv].content, valueType))
1522 if (!canConvertFromTo(m_state.registers[argv + 1].content, intType))
1524 addReadRegister(argv + 1, intType);
1527 addReadRegister(argv, valueType);
1528 setAccumulator(boolType);
1532 if (
name == u
"toString" || (
name == u
"join" && argc < 2)) {
1534 if (!canConvertFromTo(m_state.registers[argv].content, stringType))
1536 addReadRegister(argv, stringType);
1539 setAccumulator(stringType);
1543 if ((
name == u
"pop" ||
name == u
"shift") && argc == 0) {
1544 setAccumulator(valueType);
1545 m_state.setHasSideEffects(canHaveSideEffects);
1549 if (
name == u
"push" ||
name == u
"unshift") {
1550 for (
int i = 0;
i < argc; ++
i) {
1551 if (!canConvertFromTo(m_state.registers[argv +
i].content, valueType))
1555 for (
int i = 0;
i < argc; ++
i)
1556 addReadRegister(argv +
i, valueType);
1558 setAccumulator(intType);
1559 m_state.setHasSideEffects(canHaveSideEffects);
1563 if (
name == u
"reverse" && argc == 0) {
1564 setAccumulator(baseType);
1565 m_state.setHasSideEffects(canHaveSideEffects);
1569 if (
name == u
"slice" && argc < 3) {
1570 for (
int i = 0;
i < argc; ++
i) {
1571 if (!canConvertFromTo(m_state.registers[argv +
i].content, intType))
1575 for (
int i = 0;
i < argc; ++
i)
1576 addReadRegister(argv +
i, intType);
1584 if (
name == u
"splice" && argc > 0) {
1585 for (
int i = 0;
i < 2; ++
i) {
1586 if (!canConvertFromTo(m_state.registers[argv +
i].content, intType))
1590 for (
int i = 2;
i < argc; ++
i) {
1591 if (!canConvertFromTo(m_state.registers[argv +
i].content, valueType))
1595 for (
int i = 0;
i < 2; ++
i)
1596 addReadRegister(argv +
i, intType);
1598 for (
int i = 2;
i < argc; ++
i)
1599 addReadRegister(argv +
i, valueType);
1601 setAccumulator(baseType);
1602 m_state.setHasSideEffects(canHaveSideEffects);
1606 if ((
name == u
"indexOf" ||
name == u
"lastIndexOf") && argc > 0 && argc < 3) {
1607 if (!canConvertFromTo(m_state.registers[argv].content, valueType))
1611 if (!canConvertFromTo(m_state.registers[argv + 1].content, intType))
1613 addReadRegister(argv + 1, intType);
1616 addReadRegister(argv, valueType);
1617 setAccumulator(intType);
1637 m_state.setHasSideEffects(
true);
1643void QQmlJSTypePropagator::propagateScopeLookupCall(
const QString &functionName,
int argc,
int argv)
1650 if (propagateTranslationMethod(
methods, argc, argv))
1660 setError(u
"method %1 cannot be resolved."_s.arg(functionName));
1663 setError(u
"Cannot find function '%1'"_s.arg(functionName));
1665 handleUnqualifiedAccess(functionName,
true);
1676 propagateScopeLookupCall(
name, argc, argv);
1682 m_state.setHasSideEffects(
true);
1692 m_state.setHasSideEffects(
true);
1702 m_state.setHasSideEffects(
true);
1713 m_state.setHasSideEffects(
true);
1722 m_state.setHasSideEffects(
true);
1729 m_state.setHasSideEffects(
true);
1735 m_state.setHasSideEffects(
true);
1743 const auto fail = [
this,
name]() {
1744 setError(u
"Cannot statically assert the dead temporal zone check for %1"_s.arg(
1749 if (
in.isConversion()) {
1764 m_state.setHasSideEffects(
true);
1765 m_state.skipInstructionsUntilNextJumpTarget =
true;
1775 m_state.setHasSideEffects(
true);
1781 m_state.setHasSideEffects(
true);
1786 m_state.setHasSideEffects(
true);
1794 m_state.setHasSideEffects(
true);
1800 m_state.setHasSideEffects(
true);
1807 m_state.setHasSideEffects(
true);
1813 m_state.setHasSideEffects(
true);
1820 m_state.setHasSideEffects(
true);
1826 m_state.setHasSideEffects(
true);
1898 for (
int i = 0;
i < argc; ++
i)
1899 addReadRegister(
args +
i, elementType);
1908 for (
int i = 0;
i < classSize; ++
i) {
1914 for (
int i = classSize;
i < argc;
i += 3) {
1973 saveRegisterStateForJump(
offset);
1974 m_state.skipInstructionsUntilNextJumpTarget =
true;
1975 m_state.setHasSideEffects(
true);
1980 if (!canConvertFromTo(m_state.accumulatorIn(),
1982 setError(u
"cannot convert from %1 to boolean"_s
1983 .
arg(m_state.accumulatorIn().descriptiveName()));
1986 saveRegisterStateForJump(
offset);
1987 m_state.setHasSideEffects(
true);
1993 if (!canConvertFromTo(m_state.accumulatorIn(),
1995 setError(u
"cannot convert from %1 to boolean"_s
1996 .
arg(m_state.accumulatorIn().descriptiveName()));
1999 saveRegisterStateForJump(
offset);
2000 m_state.setHasSideEffects(
true);
2006 saveRegisterStateForJump(
offset);
2007 m_state.setHasSideEffects(
true);
2018 m_state.setHasSideEffects(
true);
2021void QQmlJSTypePropagator::recordEqualsNullType()
2026 addReadAccumulator(m_state.accumulatorIn());
2031void QQmlJSTypePropagator::recordEqualsIntType()
2037 addReadAccumulator(m_state.accumulatorIn());
2042void QQmlJSTypePropagator::recordEqualsType(
int lhs)
2056 const auto accumulatorIn = m_state.accumulatorIn();
2057 const auto lhsRegister = m_state.registers[lhs].content;
2063 addReadRegister(lhs, accumulatorIn);
2064 addReadAccumulator(accumulatorIn);
2066 }
else if (isNumericOrEnum(accumulatorIn) && isNumericOrEnum(lhsRegister)) {
2067 const auto targetType = isIntCompatible(accumulatorIn) && isIntCompatible(lhsRegister)
2070 addReadRegister(lhs, targetType);
2071 addReadAccumulator(targetType);
2076 addReadRegister(lhs, primitive);
2077 addReadAccumulator(primitive);
2086 addReadRegister(lhs, lhsRegister);
2087 addReadAccumulator(accumulatorIn);
2095 addReadRegister(lhs, jsval);
2096 addReadAccumulator(jsval);
2099void QQmlJSTypePropagator::recordCompareType(
int lhs)
2108 addReadRegister(lhs,
read);
2109 addReadAccumulator(
read);
2114 recordEqualsNullType();
2120 recordEqualsNullType();
2126 recordEqualsIntType();
2130 m_state.accumulatorIn())));
2135 recordEqualsIntType();
2139 m_state.accumulatorIn())));
2144 recordEqualsType(lhs);
2150 recordEqualsType(lhs);
2156 recordCompareType(lhs);
2162 recordCompareType(lhs);
2168 recordCompareType(lhs);
2174 recordCompareType(lhs);
2180 recordEqualsType(lhs);
2186 recordEqualsType(lhs);
2213 switch (m_state.accumulatorIn().variant()) {
2215 contained = m_state.accumulatorIn().scopeType();
2218 contained = m_state.accumulatorIn().scopeType();
2229 if (contained->
accessSemantics() == QQmlJSScope::AccessSemantics::Reference) {
2234 setError(u
"invalid cast from %1 to %2. You can only cast object types."_s
2235 .
arg(
input.descriptiveName(), m_state.accumulatorIn().descriptiveName()));
2244 addReadRegister(lhs,
input);
2248void QQmlJSTypePropagator::checkConversion(
2251 if (!canConvertFromTo(from, to)) {
2252 setError(u
"cannot convert from %1 to %2"_s
2260 op, m_state.accumulatorIn());
2261 checkConversion(m_state.accumulatorIn(),
type);
2262 addReadAccumulator(
type);
2263 setAccumulator(
type);
2296void QQmlJSTypePropagator::generateBinaryArithmeticOperation(
QSOperator::Op op,
int lhs)
2300 checkConversion(checkedInputRegister(lhs),
type);
2301 addReadRegister(lhs,
type);
2303 checkConversion(m_state.accumulatorIn(),
type);
2304 addReadAccumulator(
type);
2307void QQmlJSTypePropagator::generateBinaryConstArithmeticOperation(
QSOperator::Op op)
2310 op, m_state.accumulatorIn(),
2313 checkConversion(m_state.accumulatorIn(),
type);
2314 addReadAccumulator(
type);
2315 setAccumulator(
type);
2416 for (
int reg = firstReg,
end = firstReg +
count; reg <
end; ++reg)
2438 if (m_state.skipInstructionsUntilNextJumpTarget) {
2440 m_state.registers.clear();
2441 m_state.skipInstructionsUntilNextJumpTarget =
false;
2443 }
else if (m_state.skipInstructionsUntilNextJumpTarget
2460 for (
auto originRegisterStateIt =
2461 m_jumpOriginRegisterStateByTargetInstructionOffset.
constFind(currentOffset);
2462 originRegisterStateIt != m_jumpOriginRegisterStateByTargetInstructionOffset.
constEnd()
2463 && originRegisterStateIt.key() == currentOffset;
2464 ++originRegisterStateIt) {
2465 auto stateToMerge = *originRegisterStateIt;
2466 for (
auto registerIt = stateToMerge.registers.constBegin(),
2467 end = stateToMerge.registers.constEnd();
2468 registerIt !=
end; ++registerIt) {
2469 const int registerIndex = registerIt.key();
2471 auto newType = registerIt.value().content;
2472 if (!newType.isValid()) {
2473 setError(u
"When reached from offset %1, %2 is undefined"_s
2474 .
arg(stateToMerge.originatingOffset)
2475 .arg(registerName(registerIndex)));
2479 auto currentRegister = m_state.registers.find(registerIndex);
2480 if (currentRegister != m_state.registers.end())
2481 mergeRegister(registerIndex, newType, currentRegister.value().content);
2483 mergeRegister(registerIndex, newType, newType);
2495 currentInstruction.
readRegisters = m_state.takeReadRegisters();
2497 currentInstruction.
isRename = m_state.isRename();
2501 case QV4::Moth::Instr::Type::Ret:
2502 case QV4::Moth::Instr::Type::Jump:
2503 case QV4::Moth::Instr::Type::JumpFalse:
2504 case QV4::Moth::Instr::Type::JumpTrue:
2505 case QV4::Moth::Instr::Type::StoreReg:
2506 case QV4::Moth::Instr::Type::StoreElement:
2507 case QV4::Moth::Instr::Type::StoreNameSloppy:
2508 case QV4::Moth::Instr::Type::StoreProperty:
2509 case QV4::Moth::Instr::Type::SetLookup:
2510 case QV4::Moth::Instr::Type::MoveConst:
2511 case QV4::Moth::Instr::Type::MoveReg:
2512 case QV4::Moth::Instr::Type::CheckException:
2513 case QV4::Moth::Instr::Type::CreateCallContext:
2514 case QV4::Moth::Instr::Type::PopContext:
2515 case QV4::Moth::Instr::Type::JumpNoException:
2516 case QV4::Moth::Instr::Type::ThrowException:
2517 case QV4::Moth::Instr::Type::SetUnwindHandler:
2518 case QV4::Moth::Instr::Type::PushCatchContext:
2519 case QV4::Moth::Instr::Type::UnwindDispatch:
2520 case QV4::Moth::Instr::Type::InitializeBlockDeadTemporalZone:
2521 case QV4::Moth::Instr::Type::ConvertThisToObject:
2522 case QV4::Moth::Instr::Type::DeadTemporalZoneCheck:
2524 setError(u
"Instruction is not expected to populate the accumulator"_s);
2531 if ((!m_state.changedRegister().isValid() || m_state.changedRegisterIndex() !=
Accumulator)
2533 setError(u
"Instruction is expected to populate the accumulator"_s);
2541 r.content = m_state.changedRegister();
2543 r.affectedBySideEffects = m_state.isRename()
2544 && m_state.isRegisterAffectedBySideEffects(m_state.renameSourceRegisterIndex());
2545 m_state.clearChangedRegister();
2548 m_state.setHasSideEffects(
false);
2549 m_state.setIsRename(
false);
2555 auto lhsRegister = checkedInputRegister(lhs);
2556 if (!lhsRegister.isValid())
2560 op, lhsRegister, m_state.accumulatorIn());
2562 setAccumulator(
type);
2572void QQmlJSTypePropagator::saveRegisterStateForJump(
int offset)
2575 ExpectedRegisterState
state;
2576 state.registers = m_state.registers;
2578 m_state.jumpTargets.insert(jumpToOffset);
2582 const auto registerStates =
2583 m_jumpOriginRegisterStateByTargetInstructionOffset.
equal_range(jumpToOffset);
2584 for (
auto it = registerStates.first;
it != registerStates.second; ++
it) {
2585 if (
it->registers.keys() ==
state.registers.keys()
2592 m_state.needsMorePasses =
true;
2594 m_jumpOriginRegisterStateByTargetInstructionOffset.
insert(jumpToOffset,
state);
2597QString QQmlJSTypePropagator::registerName(
int registerIndex)
const
2600 return u
"accumulator"_s;
2602 && registerIndex < FirstArgument + m_function->argumentTypes.size()) {
2606 return u
"temporary register %1"_s.
arg(
2612 const auto regIt = m_state.registers.find(reg);
2613 if (regIt == m_state.registers.end()) {
2617 setError(u
"Type error: could not infer the type of an expression"_s);
2620 return regIt.value().content;
static JNINativeMethod methods[]
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
const char * constData() const noexcept
Returns a pointer to the const data stored in the byte array.
iterator find(const Key &key)
QList< Key > keys() const
Returns a list containing all the keys in the hash, in an arbitrary order.
qsizetype size() const noexcept
const_iterator constBegin() const noexcept
const_iterator constEnd() const noexcept
const_iterator constEnd() const noexcept
Returns a const \l{STL-style iterators}{STL-style iterator} pointing to the imaginary item after the ...
QPair< iterator, iterator > equal_range(const Key &key)
iterator insert(const Key &key, const T &value)
Inserts a new item with the key and a value of value.
const_iterator constFind(const Key &key) const noexcept
const QV4::Compiler::JSUnitGenerator * m_jsUnitGenerator
bool isArgument(int registerIndex) const
static bool instructionManipulatesContext(QV4::Moth::Instr::Type type)
const Function * m_function
const QQmlJSTypeResolver * m_typeResolver
QQmlJS::DiagnosticMessage * m_error
State initialState(const Function *function)
QFlatMap< int, VirtualRegister > VirtualRegisters
void setError(const QString &message, int instructionOffset)
QQmlJSRegisterContent argumentType(int registerIndex) const
void log(const QString &message, QQmlJS::LoggerWarningId id, const QQmlJS::SourceLocation &srcLocation, bool showContext=true, bool showFileName=true, const std::optional< QQmlJSFixSuggestion > &suggestion={}, const QString overrideFileName=QString())
QString descriptiveName() const
QQmlJSScope::ConstPtr scopeType() const
bool isConversion() const
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType, const QQmlJSScope::ConstPtr &type, ContentVariant variant, const QQmlJSScope::ConstPtr &scope={})
ContentVariant variant() const
QQmlJSScope::ConstPtr storedType() const
bool isEnumeration() const
QList< QQmlJSMetaMethod > method() const
QHash< QString, QQmlJSMetaProperty > properties() const
Returns all properties visible from this scope including those of base types and extensions.
QHash< QString, QQmlJSMetaMethod > methods() const
Returns all methods visible from this scope including those of base types and extensions.
bool isInCustomParserParent() const
QQmlJSScope::Ptr parentScope()
QString internalName() const
bool isReferenceType() const
AccessSemantics accessSemantics() const
static QQmlSA::Element createQQmlSAElement(const ConstPtr &)
QVector< QQmlJSScope::Ptr > childScopes()
bool isListProperty() const
QDeferredSharedPointer< const QQmlJSScope > ConstPtr
QQmlJSMetaProperty property(const QString &name) const
bool hasOwnProperty(const QString &name) const
QQmlJSScope::ConstPtr baseType() const
static QQmlJSScope::ConstPtr findCurrentQMLScope(const QQmlJSScope::ConstPtr &scope)
QQmlJS::SourceLocation sourceLocation() const
QQmlJSScope::ConstPtr valueType() const
QString id(const QQmlJSScope::ConstPtr &scope, const QQmlJSScope::ConstPtr &referrer) const
bool componentsAreBound() const
bool existsAnywhereInDocument(const QString &id) const
bool equals(const QQmlJSScope::ConstPtr &a, const QQmlJSScope::ConstPtr &b) const
QQmlJSScope::ConstPtr functionType() const
QQmlJSRegisterContent merge(const QQmlJSRegisterContent &a, const QQmlJSRegisterContent &b) const
QQmlJSRegisterContent memberType(const QQmlJSRegisterContent &type, const QString &name) const
QQmlJSScope::ConstPtr stringType() const
const QHash< QQmlJS::SourceLocation, QQmlJSMetaSignalHandler > & signalHandlers() const
QQmlJSScope::ConstPtr nullType() const
QQmlJSRegisterContent tracked(const QQmlJSRegisterContent &type) const
QQmlJSScope::ConstPtr genericType(const QQmlJSScope::ConstPtr &type, ComponentIsGeneric allowComponent=ComponentIsGeneric::No) const
QQmlJSScope::ConstPtr emptyType() const
bool registerIsStoredIn(const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr containedType(const QQmlJSRegisterContent &container) const
QQmlJSScope::ConstPtr jsPrimitiveType() const
QQmlJSRegisterContent typeForArithmeticUnaryOperation(UnaryOperator op, const QQmlJSRegisterContent &operand) const
bool isNumeric(const QQmlJSRegisterContent &type) const
QQmlJSScope::ConstPtr arrayPrototype() const
QQmlJSScope::ConstPtr boolType() const
QQmlJSScope::ConstPtr qObjectListType() const
QQmlJSScope::ConstPtr jsGlobalObject() const
bool registerContains(const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const
bool isIntegral(const QQmlJSRegisterContent &type) const
bool isPrimitive(const QQmlJSRegisterContent &type) const
QQmlJSRegisterContent builtinType(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent returnType(const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant, const QQmlJSScope::ConstPtr &scope) const
bool canConvertFromTo(const QQmlJSScope::ConstPtr &from, const QQmlJSScope::ConstPtr &to) const
bool isPrefix(const QString &name) const
QString containedTypeName(const QQmlJSRegisterContent &container, bool useFancyName=false) const
QQmlJSScope::ConstPtr jsValueType() const
QQmlJSRegisterContent globalType(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent convert(const QQmlJSRegisterContent &from, const QQmlJSRegisterContent &to) const
bool canHoldUndefined(const QQmlJSRegisterContent &content) const
QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &list) const
QQmlJSScope::ConstPtr uint32Type() const
QQmlJSScope::ConstPtr int32Type() const
QQmlJSScope::ConstPtr variantListType() const
QQmlJSScope::ConstPtr voidType() const
QQmlJSScope::ConstPtr metaObjectType() const
QQmlJSScope::ConstPtr realType() const
bool isUnsignedInteger(const QQmlJSScope::ConstPtr &type) const
QQmlJSScope::ConstPtr typeForConst(QV4::ReturnedValue rv) const
bool canAddressValueTypes() const
bool isSignedInteger(const QQmlJSScope::ConstPtr &type) const
QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name) const
QQmlJSScope::ConstPtr qObjectType() const
QQmlJSScope::ConstPtr varType() const
QQmlJSRegisterContent typeForBinaryOperation(QSOperator::Op oper, const QQmlJSRegisterContent &left, const QQmlJSRegisterContent &right) const
QQmlJSScope::ConstPtr variantMapType() const
static QQmlSA::SourceLocation createQQmlSASourceLocation(const QQmlJS::SourceLocation &jsLocation)
QList< T > values() const
iterator find(const T &value)
\macro QT_RESTRICTED_CAST_FROM_ASCII
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
const QChar at(qsizetype i) const
Returns the character at the given index position in the string.
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
int currentInstructionOffset() const
int nextInstructionOffset() const
QSet< QString >::iterator it
QList< QVariant > arguments
Combined button and popup list for selecting options.
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction function
DBusConnection const char DBusError * error
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char * method
EGLOutputLayerEXT EGLint EGLAttrib value
[5]
GLboolean GLboolean GLboolean b
GLenum GLuint GLint level
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLsizei GLenum GLenum * types
GLenum GLenum GLsizei count
GLuint GLsizei const GLchar * message
GLenum GLuint GLintptr offset
GLenum GLenum GLenum input
const QQmlJS::LoggerWarningId qmlUnqualified
const QQmlJS::LoggerWarningId qmlUseProperFunction
const QQmlJS::LoggerWarningId qmlRestrictedType
const QQmlJS::LoggerWarningId qmlMissingEnumEntry
const QQmlJS::LoggerWarningId qmlUnresolvedType
const QQmlJS::LoggerWarningId qmlReadOnlyProperty
const QQmlJS::LoggerWarningId qmlMissingProperty
const QQmlJS::LoggerWarningId qmlDeprecated
const QQmlJS::LoggerWarningId qmlMissingType
const QQmlJS::LoggerWarningId qmlAccessSingleton
const QQmlJS::LoggerWarningId qmlIncompatibleType
#define INSTR_PROLOGUE_NOT_IMPLEMENTED()
#define INSTR_PROLOGUE_NOT_IMPLEMENTED_IGNORE()
static bool isLoggingMethod(const QString &consoleMethod)
bool canCompareWithQObject(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, const QQmlJSRegisterContent &rhsContent)
bool canCompareWithQUrl(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, const QQmlJSRegisterContent &rhsContent)
bool canStrictlyCompareWithVar(const QQmlJSTypeResolver *typeResolver, const QQmlJSRegisterContent &lhsContent, const QQmlJSRegisterContent &rhsContent)
QLatin1StringView QLatin1String
#define QStringLiteral(str)
static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
ReturnedValue read(const char *data)
QT_BEGIN_NAMESPACE typedef uchar * output
QList< QQmlJSRegisterContent > argumentTypes
QQmlJSScopesById addressableScopes
QQmlJSScope::ConstPtr qmlScope
const SourceLocationTable * sourceLocations
QQmlJSScope::ConstPtr returnType
VirtualRegisters readRegisters
QQmlJSRegisterContent changedRegister
void generate_IteratorClose(int done) override
void generate_CmpEqInt(int lhsConst) override
void generate_GetLookup(int index) override
void generate_Decrement() override
void generate_CallPropertyLookup(int lookupIndex, int base, int argc, int argv) override
void generate_StoreNameStrict(int name) override
void generate_StoreElement(int base, int index) override
void generate_ConvertThisToObject() override
void generate_CloneBlockContext() override
void generate_LoadConst(int index) override
void generate_LoadLocal(int index) override
void generate_CreateUnmappedArgumentsObject() override
void generate_StoreSuperProperty(int property) override
void generate_DeleteName(int name) override
void generate_CreateCallContext() override
void generate_PopScriptContext() override
void generate_MoveRegExp(int regExpId, int destReg) override
void generate_PushWithContext() override
void generate_TypeofName(int name) override
void generate_CallQmlContextPropertyLookup(int index, int argc, int argv) override
void generate_BitXorConst(int rhsConst) override
void generate_InitializeBlockDeadTemporalZone(int firstReg, int count) override
void generate_LoadName(int nameIndex) override
void generate_StoreNameCommon(int nameIndex)
void generate_DeclareVar(int varName, int isDeletable) override
void generate_StoreProperty(int name, int base) override
void generate_GetException() override
void generate_LoadReg(int reg) override
void generate_CallGlobalLookup(int index, int argc, int argv) override
void generate_LoadTrue() override
void generate_SetLookup(int index, int base) override
void generate_UShrConst(int rhsConst) override
void endInstruction(QV4::Moth::Instr::Type instr) override
void generate_LoadImport(int index) override
void generate_PushBlockContext(int index) override
void generate_CmpGe(int lhs) override
void generate_CmpLt(int lhs) override
void generate_ToObject() override
void generate_LoadClosure(int value) override
void generate_Mul(int lhs) override
void generate_UnwindToLabel(int level, int offset) override
void generate_StoreScopedLocal(int scope, int index) override
void generate_LoadNull() override
void generate_CmpInstanceOf(int lhs) override
void generate_DestructureRestElement() override
void generate_YieldStar() override
void generate_CmpNeNull() override
void generate_JumpNoException(int offset) override
void generate_ThrowException() override
void generate_GetOptionalLookup(int index, int offset) override
void generate_Resume(int) override
void generate_BitAndConst(int rhsConst) override
void generate_LoadElement(int base) override
void generate_MoveReg(int srcReg, int destReg) override
void generate_LoadProperty(int nameIndex) override
void generate_Yield() override
void generate_CmpNe(int lhs) override
void generate_Construct(int func, int argc, int argv) override
void generate_LoadFalse() override
void generate_Ret() override
void generate_CallProperty(int name, int base, int argc, int argv) override
void generate_CmpNeInt(int lhs) override
void generate_JumpFalse(int offset) override
void generate_ConstructWithSpread(int func, int argc, int argv) override
void generate_StoreReg(int reg) override
void generate_GetIterator(int iterator) override
void generate_ShlConst(int rhs) override
void generate_BitAnd(int lhs) override
void generate_SetException() override
void generate_UMinus() override
void generate_CmpStrictNotEqual(int lhs) override
void generate_CmpStrictEqual(int lhs) override
void generate_LoadScopedLocal(int scope, int index) override
void generate_Shl(int lhs) override
void generate_UPlus() override
void generate_Debug() override
void generate_CmpEqNull() override
void generate_LoadRuntimeString(int stringId) override
void generate_Shr(int lhs) override
void generate_DefineArray(int argc, int args) override
void generate_UCompl() override
void generate_JumpNotUndefined(int offset) override
void generate_CallWithReceiver(int name, int thisObject, int argc, int argv) override
void generate_CallWithSpread(int func, int thisObject, int argc, int argv) override
void generate_GetTemplateObject(int index) override
void generate_DefineObjectLiteral(int internalClassId, int argc, int args) override
void generate_CreateRestParameter(int argIndex) override
void generate_CheckException() override
void generate_CallValue(int name, int argc, int argv) override
void generate_Mod(int lhs) override
void generate_BitOr(int lhs) override
void generate_CmpLe(int lhs) override
void generate_StoreLocal(int index) override
void generate_SetUnwindHandler(int offset) override
void generate_LoadUndefined() override
void generate_MoveConst(int constIndex, int destTemp) override
void generate_TailCall(int func, int thisObject, int argc, int argv) override
void generate_DeleteProperty(int base, int index) override
void generate_BitOrConst(int rhsConst) override
void generate_StoreNameSloppy(int nameIndex) override
void generate_BitXor(int lhs) override
void generate_Exp(int lhs) override
void generate_Div(int lhs) override
void generate_LoadSuperProperty(int property) override
void generate_CreateClass(int classIndex, int heritage, int computedNames) override
void generate_TypeofValue() override
void generate_UShr(int lhs) override
void generate_PushScriptContext(int index) override
void generate_CallName(int name, int argc, int argv) override
void generate_Jump(int offset) override
void generate_CmpEq(int lhs) override
void generate_As(int lhs) override
void generate_LoadOptionalProperty(int name, int offset) override
void generate_Sub(int lhs) override
void generate_LoadZero() override
void generate_LoadGlobalLookup(int index) override
void generate_UnwindDispatch() override
void generate_LoadInt(int value) override
void generate_IteratorNextForYieldStar(int iterator, int object) override
void generate_ShrConst(int rhs) override
void generate_CallPossiblyDirectEval(int argc, int argv) override
void generate_CmpIn(int lhs) override
void generate_JumpTrue(int offset) override
void generate_UNot() override
void generate_LoadQmlContextPropertyLookup(int index) override
void generate_PopContext() override
Verdict startInstruction(QV4::Moth::Instr::Type instr) override
void generate_PushCatchContext(int index, int name) override
void generate_CmpGt(int lhs) override
void generate_IteratorNext(int value, int done) override
QQmlJSTypePropagator(const QV4::Compiler::JSUnitGenerator *unitGenerator, const QQmlJSTypeResolver *typeResolver, QQmlJSLogger *logger, QQmlSA::PassManager *passManager=nullptr)
bool checkForEnumProblems(const QQmlJSRegisterContent &base, const QString &propertyName) const
void generate_Add(int lhs) override
void generate_LoadSuperConstructor() override
void generate_CreateMappedArgumentsObject() override
void generate_ThrowOnNullOrUndefined() override
void generate_Increment() override
InstructionAnnotations run(const Function *m_function, QQmlJS::DiagnosticMessage *error)
void generate_DeadTemporalZoneCheck(int name) override
static std::optional< QQmlJSFixSuggestion > didYouMean(const QString &userInput, QStringList candidates, QQmlJS::SourceLocation location)
QString lookupName(int index) const
ReturnedValue constant(int idx) const
int lookupNameIndex(int index) const
int getStringId(const QString &string) const
QString stringForIndex(int index) const
int jsClassSize(int jsClassId) const
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent