QmlCompiler: Create QQmlJSRegisterContent unstored
Add a separate pass to populate the stored types and only run that after we're done with all the type propagation and optimization. Task-number: QTBUG-124670 Change-Id: I740063908b22684f5d2c72d6261fad98850d8636 Reviewed-by: Olivier De Cannière <olivier.decanniere@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
9542b4b935
commit
dd731b880b
|
@ -34,6 +34,7 @@ qt_internal_add_module(QmlCompiler
|
|||
qqmljscontextualtypes_p.h
|
||||
qqmljsshadowcheck.cpp qqmljsshadowcheck_p.h
|
||||
qqmljsstoragegeneralizer.cpp qqmljsstoragegeneralizer_p.h
|
||||
qqmljsstorageinitializer.cpp qqmljsstorageinitializer_p.h
|
||||
qqmljstypedescriptionreader.cpp qqmljstypedescriptionreader_p.h
|
||||
qqmljstypepropagator.cpp qqmljstypepropagator_p.h
|
||||
qqmljstypereader.cpp qqmljstypereader_p.h
|
||||
|
|
|
@ -213,7 +213,7 @@ QT_WARNING_POP
|
|||
if (!registerIsArgument
|
||||
&& registerIndex != Accumulator
|
||||
&& registerIndex != This
|
||||
&& !registerIsStoredIn(
|
||||
&& !m_typeResolver->registerContains(
|
||||
function->registerTypes[registerIndex - firstRegisterIndex()],
|
||||
m_typeResolver->voidType())) {
|
||||
result.code += registerIt->variableName + u" = "_s;
|
||||
|
@ -223,10 +223,9 @@ QT_WARNING_POP
|
|||
const int argumentIndex = registerIndex - FirstArgument;
|
||||
const QQmlJSRegisterContent argument
|
||||
= m_function->argumentTypes[argumentIndex];
|
||||
const QQmlJSRegisterContent original
|
||||
= m_typeResolver->original(argument);
|
||||
const QQmlJSRegisterContent originalArgument = original(argument);
|
||||
|
||||
const bool needsConversion = argument != original;
|
||||
const bool needsConversion = argument != originalArgument;
|
||||
if (!isPointer && registerIt->numTracked == 1 && !needsConversion) {
|
||||
// Not a pointer, never written to, and doesn't need any initial conversion.
|
||||
// This is a readonly argument.
|
||||
|
@ -240,11 +239,11 @@ QT_WARNING_POP
|
|||
result.code += registerIt->variableName + u" = "_s;
|
||||
|
||||
const QString originalValue
|
||||
= u"(*static_cast<"_s + castTargetName(original.storedType())
|
||||
= u"(*static_cast<"_s + castTargetName(originalArgument.storedType())
|
||||
+ u"*>(argv["_s + QString::number(argumentIndex + 1) + u"]))"_s;
|
||||
|
||||
if (needsConversion)
|
||||
result.code += conversion(original, argument, originalValue);
|
||||
result.code += conversion(originalArgument, argument, originalValue);
|
||||
else
|
||||
result.code += originalValue;
|
||||
} else {
|
||||
|
@ -683,9 +682,11 @@ void QQmlJSCodeGenerator::generate_LoadQmlContextPropertyLookup(int index)
|
|||
const int nameIndex = m_jsUnitGenerator->lookupNameIndex(index);
|
||||
const QString name = m_jsUnitGenerator->stringForIndex(nameIndex);
|
||||
if (m_state.accumulatorOut().variant() == QQmlJSRegisterContent::JavaScriptGlobal) {
|
||||
// This produces a QJSValue. The QQmlJSMetaProperty used to analyze it may have more details
|
||||
// but the QQmlJSAotContext API does not reflect them.
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ conversion(
|
||||
m_typeResolver->original(m_state.accumulatorOut()), m_state.accumulatorOut(),
|
||||
m_typeResolver->jsValueType(), m_state.accumulatorOut(),
|
||||
u"aotContext->javaScriptGlobalProperty("_s + QString::number(nameIndex) + u")")
|
||||
+ u";\n"_s;
|
||||
return;
|
||||
|
@ -775,7 +776,7 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
|
|||
}
|
||||
|
||||
const QString voidAssignment = u" "_s + m_state.accumulatorVariableOut + u" = "_s +
|
||||
conversion(m_typeResolver->globalType(m_typeResolver->voidType()),
|
||||
conversion(global(m_typeResolver->voidType()),
|
||||
m_state.accumulatorOut(), QString()) + u";\n"_s;
|
||||
|
||||
QString indexName = m_state.accumulatorVariableIn;
|
||||
|
@ -812,7 +813,7 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
|
|||
|
||||
if (registerIsStoredIn(baseType, m_typeResolver->listPropertyType())) {
|
||||
// Our QQmlListProperty only keeps plain QObject*.
|
||||
const auto elementType = m_typeResolver->globalType(m_typeResolver->qObjectType());
|
||||
const auto elementType = global(m_typeResolver->qObjectType());
|
||||
|
||||
m_body += u"if ("_s + indexName + u" < "_s + baseName
|
||||
+ u".count(&"_s + baseName + u"))\n"_s;
|
||||
|
@ -825,7 +826,9 @@ void QQmlJSCodeGenerator::generate_LoadElement(int base)
|
|||
return;
|
||||
}
|
||||
|
||||
const auto elementType = m_typeResolver->valueType(baseType);
|
||||
// Since we can do .at() below, we know that we can natively store the element type.
|
||||
QQmlJSRegisterContent elementType = m_typeResolver->valueType(baseType);
|
||||
elementType = elementType.storedIn(m_typeResolver->storedType(elementType.containedType()));
|
||||
|
||||
QString access = baseName + u".at("_s + indexName + u')';
|
||||
|
||||
|
@ -865,8 +868,8 @@ void QQmlJSCodeGenerator::generate_StoreElement(int base, int index)
|
|||
const QString indexName = registerVariable(index);
|
||||
|
||||
const auto valueType = m_typeResolver->valueType(baseType);
|
||||
const auto elementType = m_typeResolver->globalType(m_typeResolver->genericType(
|
||||
m_typeResolver->containedType(valueType)));
|
||||
const auto elementType = global(m_typeResolver->genericType(
|
||||
m_typeResolver->containedType(valueType)));
|
||||
|
||||
addInclude(u"QtQml/qjslist.h"_s);
|
||||
if (!m_typeResolver->isNativeArrayIndex(indexType))
|
||||
|
@ -1078,8 +1081,7 @@ void QQmlJSCodeGenerator::generateVariantEqualityComparison(
|
|||
: m_typeResolver->containedType(storableContent);
|
||||
|
||||
if (contained->isReferenceType()) {
|
||||
const QQmlJSRegisterContent comparable
|
||||
= m_typeResolver->builtinType(m_typeResolver->qObjectType());
|
||||
const QQmlJSRegisterContent comparable = builtin(m_typeResolver->qObjectType());
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s + (invert ? u"!"_s : QString()) + u"(("
|
||||
+ varRegisterName + u".metaType().flags() & QMetaType::PointerToQObject) "_s
|
||||
+ u" && "_s + conversion(storableContent, comparable, typedRegisterName) + u" == "_s
|
||||
|
@ -1088,8 +1090,7 @@ void QQmlJSCodeGenerator::generateVariantEqualityComparison(
|
|||
}
|
||||
|
||||
if (m_typeResolver->isPrimitive(contained)) {
|
||||
const QQmlJSRegisterContent comparable
|
||||
= m_typeResolver->builtinType(m_typeResolver->jsPrimitiveType());
|
||||
const QQmlJSRegisterContent comparable = builtin(m_typeResolver->jsPrimitiveType());
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s + (invert ? u"!"_s : QString())
|
||||
+ conversion(storableContent, comparable, typedRegisterName)
|
||||
+ u".strictlyEquals("_s
|
||||
|
@ -1457,7 +1458,7 @@ void QQmlJSCodeGenerator::generate_GetLookupHelper(int index)
|
|||
if (stored->isListProperty()) {
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s;
|
||||
m_body += conversion(
|
||||
m_typeResolver->globalType(m_typeResolver->sizeType()),
|
||||
global(m_typeResolver->sizeType()),
|
||||
m_state.accumulatorOut(),
|
||||
m_state.accumulatorVariableIn + u".count("_s + u'&'
|
||||
+ m_state.accumulatorVariableIn + u')');
|
||||
|
@ -1465,7 +1466,7 @@ void QQmlJSCodeGenerator::generate_GetLookupHelper(int index)
|
|||
} else if (stored->accessSemantics() == QQmlJSScope::AccessSemantics::Sequence
|
||||
|| m_typeResolver->equals(stored, m_typeResolver->stringType())) {
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ conversion(m_typeResolver->globalType(m_typeResolver->sizeType()),
|
||||
+ conversion(global(m_typeResolver->sizeType()),
|
||||
m_state.accumulatorOut(),
|
||||
m_state.accumulatorVariableIn + u".length()"_s)
|
||||
+ u";\n"_s;
|
||||
|
@ -1476,7 +1477,7 @@ void QQmlJSCodeGenerator::generate_GetLookupHelper(int index)
|
|||
QString mapLookup = m_state.accumulatorVariableIn + u"["_s
|
||||
+ QQmlJSUtils::toLiteral(m_jsUnitGenerator->lookupName(index)) + u"]"_s;
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s;
|
||||
m_body += conversion(m_typeResolver->globalType(m_typeResolver->varType()),
|
||||
m_body += conversion(global(m_typeResolver->varType()),
|
||||
m_state.accumulatorOut(), mapLookup);
|
||||
m_body += u";\n"_s;
|
||||
} else {
|
||||
|
@ -2189,7 +2190,7 @@ bool QQmlJSCodeGenerator::inlineArrayMethod(const QString &name, int base, int a
|
|||
call += u")";
|
||||
|
||||
const auto outType = baseType.storedType()->isListProperty()
|
||||
? m_typeResolver->globalType(m_typeResolver->qObjectListType())
|
||||
? global(m_typeResolver->qObjectListType())
|
||||
: baseType;
|
||||
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
|
@ -2347,9 +2348,9 @@ void QQmlJSCodeGenerator::generate_Construct(int func, int argc, int argv)
|
|||
INJECT_TRACE_INFO(generate_Construct);
|
||||
Q_UNUSED(func);
|
||||
|
||||
const auto original = m_typeResolver->original(m_state.accumulatorOut());
|
||||
const auto originalResult = original(m_state.accumulatorOut());
|
||||
|
||||
if (m_typeResolver->registerContains(original, m_typeResolver->dateTimeType())) {
|
||||
if (m_typeResolver->registerContains(originalResult, m_typeResolver->dateTimeType())) {
|
||||
m_body += m_state.accumulatorVariableOut + u" = ";
|
||||
if (argc == 0) {
|
||||
m_body += conversion(
|
||||
|
@ -2382,7 +2383,7 @@ void QQmlJSCodeGenerator::generate_Construct(int func, int argc, int argv)
|
|||
return;
|
||||
}
|
||||
|
||||
if (m_typeResolver->registerContains(original, m_typeResolver->variantListType())) {
|
||||
if (m_typeResolver->registerContains(originalResult, m_typeResolver->variantListType())) {
|
||||
rejectIfBadArray();
|
||||
|
||||
if (argc == 1
|
||||
|
@ -2464,8 +2465,7 @@ void QQmlJSCodeGenerator::generate_ThrowException()
|
|||
|
||||
generateSetInstructionPointer();
|
||||
m_body += u"aotContext->engine->throwError("_s
|
||||
+ conversion(m_state.accumulatorIn(), m_typeResolver->globalType(
|
||||
m_typeResolver->jsValueType()),
|
||||
+ conversion(m_state.accumulatorIn(), global(m_typeResolver->jsValueType()),
|
||||
m_state.accumulatorVariableIn) + u");\n"_s;
|
||||
generateReturnError();
|
||||
m_skipUntilNextLabel = true;
|
||||
|
@ -2593,10 +2593,14 @@ void QQmlJSCodeGenerator::generate_IteratorNext(int value, int offset)
|
|||
reject(u"using non-iterator as iterator"_s);
|
||||
|
||||
m_body += u"if (" + m_state.accumulatorVariableIn + u"->hasNext(" + qjsList + u")) {\n ";
|
||||
|
||||
// We know that this works because we can do ->next() below.
|
||||
QQmlJSRegisterContent iteratorValue = m_typeResolver->valueType(iteratorContent);
|
||||
iteratorValue = iteratorValue.storedIn(iteratorValue.containedType());
|
||||
|
||||
m_body += changedRegisterVariable() + u" = "
|
||||
+ conversion(
|
||||
m_typeResolver->valueType(iteratorContent),
|
||||
m_state.changedRegister(),
|
||||
iteratorValue, m_state.changedRegister(),
|
||||
m_state.accumulatorVariableIn + u"->next(" + qjsList + u')')
|
||||
+ u";\n";
|
||||
m_body += u"} else {\n ";
|
||||
|
@ -2700,7 +2704,7 @@ void QQmlJSCodeGenerator::generate_DefineObjectLiteral(int internalClassId, int
|
|||
m_body += u"{ "_s
|
||||
+ conversion(
|
||||
registerType(nameArg),
|
||||
m_typeResolver->globalType(m_typeResolver->stringType()),
|
||||
global(m_typeResolver->stringType()),
|
||||
consumedRegisterVariable(nameArg))
|
||||
+ u", "_s;
|
||||
|
||||
|
@ -2891,15 +2895,13 @@ void QQmlJSCodeGenerator::generate_CheckException()
|
|||
void QQmlJSCodeGenerator::generate_CmpEqNull()
|
||||
{
|
||||
INJECT_TRACE_INFO(generate_CmpEqNull);
|
||||
generateEqualityOperation(
|
||||
m_typeResolver->globalType(m_typeResolver->nullType()), QString(), u"equals"_s, false);
|
||||
generateEqualityOperation(global(m_typeResolver->nullType()), QString(), u"equals"_s, false);
|
||||
}
|
||||
|
||||
void QQmlJSCodeGenerator::generate_CmpNeNull()
|
||||
{
|
||||
INJECT_TRACE_INFO(generate_CmlNeNull);
|
||||
generateEqualityOperation(
|
||||
m_typeResolver->globalType(m_typeResolver->nullType()), QString(), u"equals"_s, true);
|
||||
generateEqualityOperation(global(m_typeResolver->nullType()), QString(), u"equals"_s, true);
|
||||
}
|
||||
|
||||
QString QQmlJSCodeGenerator::getLookupPreparation(
|
||||
|
@ -2973,8 +2975,7 @@ void QQmlJSCodeGenerator::generate_CmpEqInt(int lhsConst)
|
|||
INJECT_TRACE_INFO(generate_CmpEqInt);
|
||||
|
||||
generateEqualityOperation(
|
||||
m_typeResolver->globalType(m_typeResolver->int32Type()), QString::number(lhsConst),
|
||||
u"equals"_s, false);
|
||||
global(m_typeResolver->int32Type()), QString::number(lhsConst), u"equals"_s, false);
|
||||
}
|
||||
|
||||
void QQmlJSCodeGenerator::generate_CmpNeInt(int lhsConst)
|
||||
|
@ -2982,8 +2983,7 @@ void QQmlJSCodeGenerator::generate_CmpNeInt(int lhsConst)
|
|||
INJECT_TRACE_INFO(generate_CmpNeInt);
|
||||
|
||||
generateEqualityOperation(
|
||||
m_typeResolver->globalType(m_typeResolver->int32Type()), QString::number(lhsConst),
|
||||
u"equals"_s, true);
|
||||
global(m_typeResolver->int32Type()), QString::number(lhsConst), u"equals"_s, true);
|
||||
}
|
||||
|
||||
void QQmlJSCodeGenerator::generate_CmpEq(int lhs)
|
||||
|
@ -3056,8 +3056,8 @@ void QQmlJSCodeGenerator::generate_As(int lhs)
|
|||
|
||||
// If the original output is a conversion, we're supposed to check for the contained
|
||||
// type and if it doesn't match, set the result to null or undefined.
|
||||
const QQmlJSRegisterContent originalContent = m_typeResolver->original(outputContent);
|
||||
const QQmlJSScope::ConstPtr target = originalContent.storedType()->isReferenceType()
|
||||
const QQmlJSRegisterContent originalContent = original(outputContent);
|
||||
const QQmlJSScope::ConstPtr target = originalContent.containedType()->isReferenceType()
|
||||
? m_typeResolver->containedType(originalContent)
|
||||
: m_typeResolver->extractNonVoidFromOptionalType(originalContent);
|
||||
|
||||
|
@ -3095,14 +3095,13 @@ void QQmlJSCodeGenerator::generate_As(int lhs)
|
|||
|| registerIsStoredIn(inputContent, m_typeResolver->jsPrimitiveType())) {
|
||||
|
||||
const auto source = m_typeResolver->extractNonVoidFromOptionalType(
|
||||
m_typeResolver->original(inputContent));
|
||||
original(inputContent));
|
||||
|
||||
if (source && m_typeResolver->equals(source, target)) {
|
||||
m_body += input + u".metaType() == "_s + metaType(target)
|
||||
+ u" ? " + conversion(inputContent, outputContent, input)
|
||||
+ u" : " + conversion(
|
||||
m_typeResolver->globalType(m_typeResolver->voidType()),
|
||||
outputContent, QString());
|
||||
global(m_typeResolver->voidType()), outputContent, QString());
|
||||
m_body += u";\n"_s;
|
||||
return;
|
||||
}
|
||||
|
@ -3244,7 +3243,7 @@ void QQmlJSCodeGenerator::generate_Exp(int lhs)
|
|||
Q_ASSERT(m_error->isValid() || !lhsString.isEmpty());
|
||||
Q_ASSERT(m_error->isValid() || !rhsString.isEmpty());
|
||||
|
||||
const QQmlJSRegisterContent originalOut = m_typeResolver->original(m_state.accumulatorOut());
|
||||
const QQmlJSRegisterContent originalOut = original(m_state.accumulatorOut());
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s;
|
||||
m_body += conversion(
|
||||
originalOut, m_state.accumulatorOut(),
|
||||
|
@ -3412,20 +3411,20 @@ void QQmlJSCodeGenerator::generateEqualityOperation(
|
|||
|
||||
const auto retrieveOriginal = [this](const QQmlJSRegisterContent &content) {
|
||||
const auto contained = m_typeResolver->containedType(content);
|
||||
const auto original = m_typeResolver->original(content);
|
||||
const auto containedOriginal = m_typeResolver->containedType(original);
|
||||
const auto originalContent = original(content);
|
||||
const auto containedOriginal = m_typeResolver->containedType(originalContent);
|
||||
|
||||
if (m_typeResolver->equals(
|
||||
m_typeResolver->genericType(containedOriginal), original.storedType())) {
|
||||
m_typeResolver->genericType(containedOriginal), originalContent.storedType())) {
|
||||
// The original type doesn't need any wrapping.
|
||||
return original;
|
||||
return originalContent;
|
||||
} else if (m_typeResolver->equals(contained, containedOriginal)) {
|
||||
if (original.isConversion()) {
|
||||
if (originalContent.isConversion()) {
|
||||
// The original conversion origins are more accurate
|
||||
return original.storedIn(content.storedType());
|
||||
return originalContent.storedIn(content.storedType());
|
||||
}
|
||||
} else if (m_typeResolver->canHold(contained, containedOriginal)) {
|
||||
return original.storedIn(content.storedType());
|
||||
return originalContent.storedIn(content.storedType());
|
||||
}
|
||||
|
||||
return content;
|
||||
|
@ -3599,7 +3598,7 @@ void QQmlJSCodeGenerator::generateCompareOperation(int lhs, const QString &cppOp
|
|||
const auto lhsType = registerType(lhs);
|
||||
const QQmlJSScope::ConstPtr compareType =
|
||||
m_typeResolver->isNumeric(lhsType) && m_typeResolver->isNumeric(m_state.accumulatorIn())
|
||||
? m_typeResolver->merge(lhsType, m_state.accumulatorIn()).storedType()
|
||||
? m_typeResolver->merge(lhsType.storedType(), m_state.accumulatorIn().storedType())
|
||||
: m_typeResolver->jsPrimitiveType();
|
||||
|
||||
m_body += conversion(
|
||||
|
@ -3638,7 +3637,7 @@ void QQmlJSCodeGenerator::generateArithmeticOperation(
|
|||
Q_ASSERT(m_error->isValid() || !lhs.isEmpty());
|
||||
Q_ASSERT(m_error->isValid() || !rhs.isEmpty());
|
||||
|
||||
const QQmlJSRegisterContent originalOut = m_typeResolver->original(m_state.accumulatorOut());
|
||||
const QQmlJSRegisterContent originalOut = original(m_state.accumulatorOut());
|
||||
m_body += m_state.accumulatorVariableOut;
|
||||
m_body += u" = "_s;
|
||||
const QString explicitCast
|
||||
|
@ -3656,7 +3655,7 @@ void QQmlJSCodeGenerator::generateArithmeticConstOperation(int rhsConst, const Q
|
|||
generateArithmeticOperation(
|
||||
conversion(m_state.accumulatorIn(), m_state.readAccumulator(),
|
||||
consumedAccumulatorVariableIn()),
|
||||
conversion(m_typeResolver->globalType(m_typeResolver->int32Type()),
|
||||
conversion(global(m_typeResolver->int32Type()),
|
||||
m_state.readAccumulator(), QString::number(rhsConst)),
|
||||
cppOperator);
|
||||
}
|
||||
|
@ -3664,7 +3663,7 @@ void QQmlJSCodeGenerator::generateArithmeticConstOperation(int rhsConst, const Q
|
|||
void QQmlJSCodeGenerator::generateUnaryOperation(const QString &cppOperator)
|
||||
{
|
||||
const auto var = conversion(m_state.accumulatorIn(),
|
||||
m_typeResolver->original(m_state.readAccumulator()),
|
||||
original(m_state.readAccumulator()),
|
||||
consumedAccumulatorVariableIn());
|
||||
|
||||
if (var == m_state.accumulatorVariableOut) {
|
||||
|
@ -3672,8 +3671,8 @@ void QQmlJSCodeGenerator::generateUnaryOperation(const QString &cppOperator)
|
|||
return;
|
||||
}
|
||||
|
||||
const auto original = m_typeResolver->original(m_state.accumulatorOut());
|
||||
if (m_state.accumulatorOut() == original) {
|
||||
const auto originalResult = original(m_state.accumulatorOut());
|
||||
if (m_state.accumulatorOut() == originalResult) {
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s + var + u";\n"_s;
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ cppOperator + m_state.accumulatorVariableOut + u";\n"_s;
|
||||
|
@ -3681,7 +3680,7 @@ void QQmlJSCodeGenerator::generateUnaryOperation(const QString &cppOperator)
|
|||
}
|
||||
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s + conversion(
|
||||
original, m_state.accumulatorOut(), cppOperator + var) + u";\n"_s;
|
||||
originalResult, m_state.accumulatorOut(), cppOperator + var) + u";\n"_s;
|
||||
}
|
||||
|
||||
void QQmlJSCodeGenerator::generateInPlaceOperation(const QString &cppOperator)
|
||||
|
@ -3699,8 +3698,8 @@ void QQmlJSCodeGenerator::generateInPlaceOperation(const QString &cppOperator)
|
|||
const QString var = conversion(m_state.accumulatorIn(), m_state.readAccumulator(),
|
||||
consumedAccumulatorVariableIn());
|
||||
|
||||
const auto original = m_typeResolver->original(m_state.accumulatorOut());
|
||||
if (m_state.accumulatorOut() == original) {
|
||||
const auto originalResult = original(m_state.accumulatorOut());
|
||||
if (m_state.accumulatorOut() == originalResult) {
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s + var + u";\n"_s;
|
||||
m_body += cppOperator + m_state.accumulatorVariableOut + u";\n"_s;
|
||||
return;
|
||||
|
@ -3709,7 +3708,7 @@ void QQmlJSCodeGenerator::generateInPlaceOperation(const QString &cppOperator)
|
|||
m_body += u"{\n"_s;
|
||||
m_body += u"auto converted = "_s + var + u";\n"_s;
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s + conversion(
|
||||
original, m_state.accumulatorOut(), u'('
|
||||
originalResult, m_state.accumulatorOut(), u'('
|
||||
+ cppOperator + u"converted)"_s) + u";\n"_s;
|
||||
m_body += u"}\n"_s;
|
||||
}
|
||||
|
@ -4024,7 +4023,7 @@ QString QQmlJSCodeGenerator::convertStored(
|
|||
return variable;
|
||||
|
||||
const auto isBoolOrNumber = [&](const QQmlJSScope::ConstPtr &type) {
|
||||
return m_typeResolver->isNumeric(m_typeResolver->globalType(type))
|
||||
return m_typeResolver->isNumeric(type)
|
||||
|| m_typeResolver->equals(type, m_typeResolver->boolType())
|
||||
|| type->scopeType() == QQmlSA::ScopeType::EnumScope;
|
||||
};
|
||||
|
@ -4259,9 +4258,7 @@ QString QQmlJSCodeGenerator::convertContained(const QQmlJSRegisterContent &from,
|
|||
input = variable;
|
||||
argPointer = contentPointer(from, u"arg"_s);
|
||||
} else {
|
||||
const QQmlJSRegisterContent argument
|
||||
= m_typeResolver->globalType(argumentType)
|
||||
.storedIn(m_typeResolver->genericType(argumentType));
|
||||
const QQmlJSRegisterContent argument = global(argumentType);
|
||||
input = conversion(from, argument, variable);
|
||||
argPointer = contentPointer(argument, u"arg"_s);
|
||||
}
|
||||
|
@ -4274,7 +4271,7 @@ QString QQmlJSCodeGenerator::convertContained(const QQmlJSRegisterContent &from,
|
|||
+ u", "_s + argPointer + u"); }()"_s;
|
||||
}
|
||||
|
||||
const auto originalFrom = m_typeResolver->original(from);
|
||||
const auto originalFrom = original(from);
|
||||
const auto containedOriginalFrom = m_typeResolver->containedType(originalFrom);
|
||||
if (!m_typeResolver->equals(containedFrom, containedOriginalFrom)
|
||||
&& m_typeResolver->canHold(containedFrom, containedOriginalFrom)) {
|
||||
|
@ -4320,7 +4317,7 @@ QQmlJSCodeGenerator::AccumulatorConverter::AccumulatorConverter(QQmlJSCodeGenera
|
|||
|
||||
const bool storable = isTypeStorable(resolver, origStored);
|
||||
generator->m_state.accumulatorVariableOut = storable ? u"retrieved"_s : QString();
|
||||
generator->m_state.setRegister(Accumulator, resolver->original(accumulatorOut));
|
||||
generator->m_state.setRegister(Accumulator, generator->original(accumulatorOut));
|
||||
generator->m_body += u"{\n"_s;
|
||||
if (storable) {
|
||||
generator->m_body += origStored->augmentedInternalName() + u' '
|
||||
|
|
|
@ -230,7 +230,9 @@ protected:
|
|||
// we can convert by stored type.
|
||||
return convertStored(from, to.storedType(), variable);
|
||||
} else {
|
||||
return convertContained(m_typeResolver->globalType(from), to, variable);
|
||||
return convertContained(
|
||||
m_typeResolver->globalType(from).storedIn(m_typeResolver->storedType(from)),
|
||||
to, variable);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -335,6 +337,22 @@ private:
|
|||
const QQmlJSScope::ConstPtr &required, const QQmlJSRegisterContent &actual,
|
||||
const QString &variable, const QString &errorMessage);
|
||||
|
||||
QQmlJSRegisterContent original(const QQmlJSRegisterContent &tracked)
|
||||
{
|
||||
const QQmlJSRegisterContent restored = m_typeResolver->original(tracked);
|
||||
return restored.storedIn(m_typeResolver->originalType(tracked.storedType()));
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent global(const QQmlJSScope::ConstPtr &contained)
|
||||
{
|
||||
return m_typeResolver->globalType(contained).storedIn(contained);
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent builtin(const QQmlJSScope::ConstPtr &contained)
|
||||
{
|
||||
return m_typeResolver->builtinType(contained).storedIn(contained);
|
||||
}
|
||||
|
||||
bool registerIsStoredIn(
|
||||
const QQmlJSRegisterContent ®, const QQmlJSScope::ConstPtr &type) const
|
||||
{
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <private/qqmljsparser_p.h>
|
||||
#include <private/qqmljsshadowcheck_p.h>
|
||||
#include <private/qqmljsstoragegeneralizer_p.h>
|
||||
#include <private/qqmljsstorageinitializer_p.h>
|
||||
#include <private/qqmljstypepropagator_p.h>
|
||||
|
||||
#include <QtCore/qfile.h>
|
||||
|
@ -775,8 +776,13 @@ QQmlJSAotFunction QQmlJSAotCompiler::doCompile(
|
|||
if (error->isValid())
|
||||
return compileError();
|
||||
|
||||
QQmlJSStorageInitializer initializer(
|
||||
m_unitGenerator, &m_typeResolver, m_logger, blocks, annotations);
|
||||
passResult = initializer.run(function, error);
|
||||
|
||||
// Generalize all arguments, registers, and the return type.
|
||||
QQmlJSStorageGeneralizer generalizer(m_unitGenerator, &m_typeResolver, m_logger, blocks, annotations);
|
||||
QQmlJSStorageGeneralizer generalizer(
|
||||
m_unitGenerator, &m_typeResolver, m_logger, blocks, annotations);
|
||||
passResult = generalizer.run(function, error);
|
||||
if (error->isValid())
|
||||
return compileError();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QtQmlCompiler/private/qqmljsimportvisitor_p.h>
|
||||
#include <QtQmlCompiler/private/qqmljsshadowcheck_p.h>
|
||||
#include <QtQmlCompiler/private/qqmljsstoragegeneralizer_p.h>
|
||||
#include <QtQmlCompiler/private/qqmljsstorageinitializer_p.h>
|
||||
#include <QtQmlCompiler/private/qqmljstypepropagator_p.h>
|
||||
#include <QtQmlCompiler/private/qqmljsfunctioninitializer_p.h>
|
||||
|
||||
|
@ -91,6 +92,12 @@ bool QQmlJSLinterCodegen::analyzeFunction(const QV4::Compiler::Context *context,
|
|||
shadowCheck.run(function, error);
|
||||
}
|
||||
|
||||
if (!error->isValid()) {
|
||||
QQmlJSStorageInitializer initializer(m_unitGenerator, &m_typeResolver, m_logger,
|
||||
basicBlocks, annotations);
|
||||
initializer.run(function, error);
|
||||
}
|
||||
|
||||
if (!error->isValid()) {
|
||||
QQmlJSStorageGeneralizer generalizer(m_unitGenerator, &m_typeResolver, m_logger,
|
||||
basicBlocks, annotations);
|
||||
|
|
|
@ -84,11 +84,7 @@ void QQmlJSOptimizations::populateReaderLocations()
|
|||
it->second.changedRegister = QQmlJSRegisterContent();
|
||||
} else {
|
||||
// void the output, rather than deleting it. We still need its variant.
|
||||
bool adjusted = m_typeResolver->adjustTrackedType(
|
||||
it->second.changedRegister.storedType(), m_typeResolver->voidType());
|
||||
Q_ASSERT(adjusted); // Can always convert to void
|
||||
|
||||
adjusted = m_typeResolver->adjustTrackedType(
|
||||
const bool adjusted = m_typeResolver->adjustTrackedType(
|
||||
m_typeResolver->containedType(it->second.changedRegister),
|
||||
m_typeResolver->voidType());
|
||||
Q_ASSERT(adjusted); // Can always convert to void
|
||||
|
@ -315,13 +311,6 @@ void QQmlJSOptimizations::adjustTypes()
|
|||
}
|
||||
};
|
||||
|
||||
const auto transformRegister = [&](const QQmlJSRegisterContent &content) {
|
||||
const QQmlJSScope::ConstPtr conversion
|
||||
= m_typeResolver->storedType(m_typeResolver->containedType(content));
|
||||
if (!m_typeResolver->adjustTrackedType(content.storedType(), conversion))
|
||||
setError(adjustErrorMessage(content.storedType(), conversion));
|
||||
};
|
||||
|
||||
// Handle the array definitions first.
|
||||
// Changing the array type changes the expected element types.
|
||||
auto adjustArray = [&](int instructionOffset, int mode) {
|
||||
|
@ -354,9 +343,6 @@ void QQmlJSOptimizations::adjustTypes()
|
|||
|| !m_typeResolver->equals(contained, m_typeResolver->realType())) {
|
||||
if (!m_typeResolver->adjustTrackedType(contained, valueType))
|
||||
setError(adjustErrorMessage(contained, valueType));
|
||||
|
||||
// We still need to adjust the stored type, too.
|
||||
transformRegister(content);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -412,9 +398,6 @@ void QQmlJSOptimizations::adjustTypes()
|
|||
const QQmlJSScope::ConstPtr contained = m_typeResolver->containedType(content);
|
||||
if (!m_typeResolver->adjustTrackedType(contained, propType))
|
||||
setError(adjustErrorMessage(contained, propType));
|
||||
|
||||
// We still need to adjust the stored type, too.
|
||||
transformRegister(content);
|
||||
}
|
||||
|
||||
// The others cannot be adjusted. We don't know their names, yet.
|
||||
|
@ -456,9 +439,6 @@ void QQmlJSOptimizations::adjustTypes()
|
|||
|
||||
NewVirtualRegisters newRegisters;
|
||||
for (auto i = m_annotations.begin(), iEnd = m_annotations.end(); i != iEnd; ++i) {
|
||||
if (i->second.changedRegisterIndex != InvalidRegister)
|
||||
transformRegister(i->second.changedRegister);
|
||||
|
||||
for (auto conversion = i->second.typeConversions.begin(),
|
||||
conversionEnd = i->second.typeConversions.end(); conversion != conversionEnd;
|
||||
++conversion) {
|
||||
|
@ -475,7 +455,6 @@ void QQmlJSOptimizations::adjustTypes()
|
|||
if (!m_typeResolver->adjustTrackedType(conversionResult, newResult))
|
||||
setError(adjustErrorMessage(conversionResult, newResult));
|
||||
}
|
||||
transformRegister(content);
|
||||
newRegisters.appendOrdered(conversion);
|
||||
}
|
||||
i->second.typeConversions = newRegisters.take();
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qqmljsregistercontent_p.h"
|
||||
#include "qqmljstyperesolver_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
|
@ -121,82 +120,59 @@ QQmlJSScope::ConstPtr QQmlJSRegisterContent::containedType() const
|
|||
Q_UNREACHABLE_RETURN({});
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QQmlJSScope::ConstPtr &type,
|
||||
int resultLookupIndex,
|
||||
QQmlJSRegisterContent::ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(
|
||||
const QQmlJSScope::ConstPtr &type, int resultLookupIndex,
|
||||
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSScope::ConstPtr &scope)
|
||||
{
|
||||
QQmlJSRegisterContent result(storedType, scope, variant);
|
||||
QQmlJSRegisterContent result(scope, variant);
|
||||
result.m_content = std::make_pair(type, resultLookupIndex);
|
||||
return result;
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QQmlJSMetaProperty &property,
|
||||
int baseLookupIndex, int resultLookupIndex,
|
||||
QQmlJSRegisterContent::ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(
|
||||
const QQmlJSMetaProperty &property, int baseLookupIndex, int resultLookupIndex,
|
||||
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSScope::ConstPtr &scope)
|
||||
{
|
||||
QQmlJSRegisterContent result(storedType, scope, variant);
|
||||
QQmlJSRegisterContent result(scope, variant);
|
||||
result.m_content = PropertyLookup { property, baseLookupIndex, resultLookupIndex};
|
||||
return result;
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QQmlJSMetaEnum &enumeration,
|
||||
const QString &enumMember,
|
||||
QQmlJSRegisterContent::ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(
|
||||
const QQmlJSMetaEnum &enumeration, const QString &enumMember,
|
||||
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSScope::ConstPtr &scope)
|
||||
{
|
||||
QQmlJSRegisterContent result(storedType, scope, variant);
|
||||
QQmlJSRegisterContent result(scope, variant);
|
||||
result.m_content = std::make_pair(enumeration, enumMember);
|
||||
return result;
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QList<QQmlJSMetaMethod> &methods,
|
||||
QQmlJSRegisterContent::ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(
|
||||
const QList<QQmlJSMetaMethod> &methods, const QQmlJSScope::ConstPtr &methodType,
|
||||
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSScope::ConstPtr &scope)
|
||||
{
|
||||
// Methods can only be stored in QJSValue.
|
||||
Q_ASSERT(storedType->internalName() == u"QJSValue"_s);
|
||||
QQmlJSRegisterContent result(storedType, scope, variant);
|
||||
result.m_content = std::make_pair(methods, storedType);
|
||||
Q_ASSERT(methodType->internalName() == u"QJSValue"_s);
|
||||
QQmlJSRegisterContent result(scope, variant);
|
||||
result.m_content = std::make_pair(methods, methodType);
|
||||
return result;
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(const QQmlJSScope::ConstPtr &storedType,
|
||||
uint importNamespaceStringId,
|
||||
QQmlJSRegisterContent::ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(
|
||||
uint importNamespaceStringId, const QQmlJSScope::ConstPtr &importNamespaceType,
|
||||
QQmlJSRegisterContent::ContentVariant variant, const QQmlJSScope::ConstPtr &scope)
|
||||
{
|
||||
QQmlJSRegisterContent result(storedType, scope, variant);
|
||||
switch (variant) {
|
||||
case ScopeModulePrefix:
|
||||
// We don't store scope module prefixes
|
||||
result.m_content = std::make_pair(importNamespaceStringId, storedType);
|
||||
break;
|
||||
case ObjectModulePrefix:
|
||||
// We need to pass the original object through.
|
||||
result.m_content = std::make_pair(importNamespaceStringId, scope);
|
||||
break;
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent result(scope, variant);
|
||||
result.m_content = std::make_pair(importNamespaceStringId, importNamespaceType);
|
||||
return result;
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QList<QQmlJSScope::ConstPtr> &origins,
|
||||
const QQmlJSScope::ConstPtr &conversion,
|
||||
const QQmlJSScope::ConstPtr &conversionScope,
|
||||
ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
QQmlJSRegisterContent QQmlJSRegisterContent::create(
|
||||
const QList<QQmlJSScope::ConstPtr> &origins, const QQmlJSScope::ConstPtr &conversion,
|
||||
const QQmlJSScope::ConstPtr &conversionScope, ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
{
|
||||
QQmlJSRegisterContent result(storedType, scope, variant);
|
||||
QQmlJSRegisterContent result(scope, variant);
|
||||
result.m_content = ConvertedTypes { origins, conversion, conversionScope };
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -186,33 +186,30 @@ public:
|
|||
Q_UNREACHABLE_RETURN(seed);
|
||||
}
|
||||
|
||||
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QQmlJSScope::ConstPtr &type,
|
||||
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &type,
|
||||
int resultLookupIndex, ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope = {});
|
||||
|
||||
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QQmlJSMetaProperty &property,
|
||||
static QQmlJSRegisterContent create(const QQmlJSMetaProperty &property,
|
||||
int baseLookupIndex, int resultLookupIndex,
|
||||
ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope);
|
||||
|
||||
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QQmlJSMetaEnum &enumeration,
|
||||
static QQmlJSRegisterContent create(const QQmlJSMetaEnum &enumeration,
|
||||
const QString &enumMember, ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope);
|
||||
|
||||
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QList<QQmlJSMetaMethod> &methods,
|
||||
static QQmlJSRegisterContent create(const QList<QQmlJSMetaMethod> &methods,
|
||||
const QQmlJSScope::ConstPtr &methodType,
|
||||
ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope);
|
||||
|
||||
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
|
||||
uint importNamespaceStringId, ContentVariant variant,
|
||||
static QQmlJSRegisterContent create(uint importNamespaceStringId,
|
||||
const QQmlJSScope::ConstPtr &importNamespaceType,
|
||||
ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope = {});
|
||||
|
||||
static QQmlJSRegisterContent create(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QList<QQmlJSScope::ConstPtr> &origins,
|
||||
static QQmlJSRegisterContent create(const QList<QQmlJSScope::ConstPtr> &origins,
|
||||
const QQmlJSScope::ConstPtr &conversion,
|
||||
const QQmlJSScope::ConstPtr &conversionScope,
|
||||
ContentVariant variant,
|
||||
|
@ -292,9 +289,8 @@ private:
|
|||
ConvertedTypes
|
||||
>;
|
||||
|
||||
QQmlJSRegisterContent(const QQmlJSScope::ConstPtr &storedType,
|
||||
const QQmlJSScope::ConstPtr &scope, ContentVariant variant)
|
||||
: m_storedType(storedType), m_scope(scope), m_variant(variant)
|
||||
QQmlJSRegisterContent(const QQmlJSScope::ConstPtr &scope, ContentVariant variant)
|
||||
: m_scope(scope), m_variant(variant)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -192,8 +192,6 @@ QQmlJSShadowCheck::Shadowability QQmlJSShadowCheck::checkShadowing(
|
|||
InstructionAnnotation ¤tAnnotation = m_annotations[currentInstructionOffset()];
|
||||
|
||||
if (currentAnnotation.changedRegisterIndex != InvalidRegister) {
|
||||
m_typeResolver->adjustOriginalType(
|
||||
currentAnnotation.changedRegister.storedType(), varType);
|
||||
m_typeResolver->adjustOriginalType(
|
||||
m_typeResolver->containedType(currentAnnotation.changedRegister), varType);
|
||||
m_adjustedTypes.insert(currentAnnotation.changedRegister);
|
||||
|
|
|
@ -22,6 +22,7 @@ QT_BEGIN_NAMESPACE
|
|||
QQmlJSCompilePass::BlocksAndAnnotations
|
||||
QQmlJSStorageGeneralizer::run(Function *function, QQmlJS::DiagnosticMessage *error)
|
||||
{
|
||||
m_function = function;
|
||||
m_error = error;
|
||||
|
||||
if (QQmlJSRegisterContent &returnType = function->returnType; returnType.isValid()) {
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#include "qqmljsstorageinitializer_p.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
/*!
|
||||
* \internal
|
||||
* \class QQmlJSStorageInitializer
|
||||
*
|
||||
* The QQmlJSStorageInitializer is a compile pass that initializes the storage
|
||||
* for all register contents.
|
||||
*
|
||||
* QQmlJSStorageInitializer does not have to use the byte code at all but
|
||||
* operates only on the annotations and the function description.
|
||||
*/
|
||||
|
||||
QQmlJSCompilePass::BlocksAndAnnotations
|
||||
QQmlJSStorageInitializer::run(Function *function, QQmlJS::DiagnosticMessage *error)
|
||||
{
|
||||
m_function = function;
|
||||
m_error = error;
|
||||
|
||||
if (QQmlJSRegisterContent &returnType = function->returnType; returnType.isValid()) {
|
||||
if (const QQmlJSScope::ConstPtr stored
|
||||
= m_typeResolver->storedType(returnType.containedType())) {
|
||||
returnType = returnType.storedIn(m_typeResolver->trackedType(stored));
|
||||
} else {
|
||||
setError(QStringLiteral("Cannot store the return type %1.")
|
||||
.arg(returnType.containedType()->internalName()));
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
const auto storeRegister = [&](QQmlJSRegisterContent &content) {
|
||||
if (!content.isValid())
|
||||
return;
|
||||
|
||||
const QQmlJSScope::ConstPtr original
|
||||
= m_typeResolver->originalType(content.containedType());
|
||||
const QQmlJSScope::ConstPtr originalStored = m_typeResolver->storedType(original);
|
||||
const QQmlJSScope::ConstPtr originalTracked = m_typeResolver->trackedType(originalStored);
|
||||
content = content.storedIn(originalTracked);
|
||||
|
||||
const QQmlJSScope::ConstPtr adjustedStored
|
||||
= m_typeResolver->storedType(content.containedType());
|
||||
|
||||
if (!m_typeResolver->adjustTrackedType(originalTracked, adjustedStored)) {
|
||||
setError(QStringLiteral("Cannot adjust stored type for %1.")
|
||||
.arg(content.containedType()->internalName()));
|
||||
}
|
||||
};
|
||||
|
||||
const auto storeRegisters = [&](VirtualRegisters ®isters) {
|
||||
for (auto j = registers.begin(), jEnd = registers.end(); j != jEnd; ++j)
|
||||
storeRegister(j.value().content);
|
||||
};
|
||||
|
||||
storeRegister(function->qmlScope);
|
||||
|
||||
for (QQmlJSRegisterContent &argument : function->argumentTypes) {
|
||||
Q_ASSERT(argument.isValid());
|
||||
storeRegister(argument);
|
||||
}
|
||||
|
||||
for (QQmlJSRegisterContent &argument : function->registerTypes) {
|
||||
Q_ASSERT(argument.isValid());
|
||||
storeRegister(argument);
|
||||
}
|
||||
|
||||
for (auto i = m_annotations.begin(), iEnd = m_annotations.end(); i != iEnd; ++i) {
|
||||
storeRegister(i->second.changedRegister);
|
||||
storeRegisters(i->second.typeConversions);
|
||||
storeRegisters(i->second.readRegisters);
|
||||
}
|
||||
|
||||
return { std::move(m_basicBlocks), std::move(m_annotations) };
|
||||
}
|
||||
|
||||
QT_END_NAMESPACE
|
|
@ -0,0 +1,40 @@
|
|||
// Copyright (C) 2024 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QQMLJSSTORAGEINITIALIZER_P_H
|
||||
#define QQMLJSSTORAGEINITIALIZER_P_H
|
||||
|
||||
//
|
||||
// W A R N I N G
|
||||
// -------------
|
||||
//
|
||||
// This file is not part of the Qt API. It exists purely as an
|
||||
// implementation detail. This header file may change from version to
|
||||
// version without notice, or even be removed.
|
||||
//
|
||||
// We mean it.
|
||||
|
||||
#include <private/qqmljscompilepass_p.h>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
|
||||
class Q_QMLCOMPILER_EXPORT QQmlJSStorageInitializer : public QQmlJSCompilePass
|
||||
{
|
||||
public:
|
||||
QQmlJSStorageInitializer(const QV4::Compiler::JSUnitGenerator *jsUnitGenerator,
|
||||
const QQmlJSTypeResolver *typeResolver, QQmlJSLogger *logger,
|
||||
BasicBlocks basicBlocks, InstructionAnnotations annotations)
|
||||
: QQmlJSCompilePass(jsUnitGenerator, typeResolver, logger, basicBlocks, annotations)
|
||||
{}
|
||||
|
||||
BlocksAndAnnotations run(Function *function, QQmlJS::DiagnosticMessage *error);
|
||||
|
||||
protected:
|
||||
// We don't have to use the byte code here. We only transform the instruction annotations.
|
||||
Verdict startInstruction(QV4::Moth::Instr::Type) override { return SkipInstruction; }
|
||||
void endInstruction(QV4::Moth::Instr::Type) override {}
|
||||
};
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif // QQMLJSSTORAGEINITIALIZER_P_H
|
|
@ -575,7 +575,7 @@ void QQmlJSTypePropagator::generate_LoadQmlContextPropertyLookup(int index)
|
|||
if (!m_state.accumulatorOut().isValid() && m_typeResolver->isPrefix(name)) {
|
||||
const QQmlJSRegisterContent inType = m_typeResolver->globalType(qmlScope);
|
||||
setAccumulator(QQmlJSRegisterContent::create(
|
||||
m_typeResolver->voidType(), nameIndex, QQmlJSRegisterContent::ScopeModulePrefix,
|
||||
nameIndex, m_typeResolver->voidType(), QQmlJSRegisterContent::ScopeModulePrefix,
|
||||
m_typeResolver->containedType(inType)));
|
||||
return;
|
||||
}
|
||||
|
@ -833,8 +833,8 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName,
|
|||
Q_ASSERT(m_state.accumulatorIn().isValid());
|
||||
addReadAccumulator(m_state.accumulatorIn());
|
||||
setAccumulator(QQmlJSRegisterContent::create(
|
||||
m_state.accumulatorIn().storedType(),
|
||||
m_jsUnitGenerator->getStringId(propertyName),
|
||||
m_state.accumulatorIn().containedType(),
|
||||
QQmlJSRegisterContent::ObjectModulePrefix,
|
||||
m_typeResolver->containedType(m_state.accumulatorIn())));
|
||||
return;
|
||||
|
@ -929,7 +929,7 @@ void QQmlJSTypePropagator::propagatePropertyLookup(const QString &propertyName,
|
|||
prop.setType(m_typeResolver->realType());
|
||||
setAccumulator(
|
||||
QQmlJSRegisterContent::create(
|
||||
m_typeResolver->realType(), prop, m_state.accumulatorIn().resultLookupIndex(), lookupIndex,
|
||||
prop, m_state.accumulatorIn().resultLookupIndex(), lookupIndex,
|
||||
QQmlJSRegisterContent::GenericObjectProperty, mathObject)
|
||||
);
|
||||
|
||||
|
@ -1058,7 +1058,7 @@ void QQmlJSTypePropagator::generate_StoreProperty(int nameIndex, int base)
|
|||
|
||||
const QQmlJSScope::ConstPtr varType = m_typeResolver->varType();
|
||||
const QQmlJSRegisterContent readType = m_typeResolver->canHoldUndefined(m_state.accumulatorIn())
|
||||
? property.storedIn(varType).castTo(varType)
|
||||
? property.castTo(varType)
|
||||
: std::move(property);
|
||||
addReadAccumulator(readType);
|
||||
addReadRegister(base, callBase);
|
||||
|
|
|
@ -406,35 +406,35 @@ QQmlJSRegisterContent QQmlJSTypeResolver::transformed(
|
|||
{
|
||||
if (origin.isType()) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
(this->*op)(origin.storedType()), (this->*op)(origin.type()),
|
||||
origin.resultLookupIndex(), origin.variant(), (this->*op)(origin.scopeType()));
|
||||
(this->*op)(origin.type()), origin.resultLookupIndex(), origin.variant(),
|
||||
(this->*op)(origin.scopeType()));
|
||||
}
|
||||
|
||||
if (origin.isProperty()) {
|
||||
QQmlJSMetaProperty prop = origin.property();
|
||||
prop.setType((this->*op)(prop.type()));
|
||||
return QQmlJSRegisterContent::create(
|
||||
(this->*op)(origin.storedType()), prop, origin.baseLookupIndex(),
|
||||
origin.resultLookupIndex(), origin.variant(), (this->*op)(origin.scopeType()));
|
||||
prop, origin.baseLookupIndex(), origin.resultLookupIndex(), origin.variant(),
|
||||
(this->*op)(origin.scopeType()));
|
||||
}
|
||||
|
||||
if (origin.isEnumeration()) {
|
||||
QQmlJSMetaEnum enumeration = origin.enumeration();
|
||||
enumeration.setType((this->*op)(enumeration.type()));
|
||||
return QQmlJSRegisterContent::create(
|
||||
(this->*op)(origin.storedType()), enumeration, origin.enumMember(),
|
||||
origin.variant(), (this->*op)(origin.scopeType()));
|
||||
enumeration, origin.enumMember(), origin.variant(),
|
||||
(this->*op)(origin.scopeType()));
|
||||
}
|
||||
|
||||
if (origin.isMethod()) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
(this->*op)(origin.storedType()), origin.method(), origin.variant(),
|
||||
origin.method(), (this->*op)(origin.methodType()), origin.variant(),
|
||||
(this->*op)(origin.scopeType()));
|
||||
}
|
||||
|
||||
if (origin.isImportNamespace()) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
(this->*op)(origin.storedType()), origin.importNamespace(),
|
||||
origin.importNamespace(), (this->*op)(origin.importNamespaceType()),
|
||||
origin.variant(), (this->*op)(origin.scopeType()));
|
||||
}
|
||||
|
||||
|
@ -453,7 +453,6 @@ QQmlJSRegisterContent QQmlJSTypeResolver::transformed(
|
|||
}
|
||||
|
||||
return QQmlJSRegisterContent::create(
|
||||
(this->*op)(origin.storedType()),
|
||||
transformedOrigins,
|
||||
(this->*op)(origin.conversionResult()),
|
||||
(this->*op)(origin.conversionResultScope()),
|
||||
|
@ -495,13 +494,13 @@ QQmlJSRegisterContent QQmlJSTypeResolver::registerContentForName(
|
|||
|
||||
if (type->isSingleton()) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(type), type, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
type, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::Singleton, scopeType);
|
||||
}
|
||||
|
||||
if (type->isScript()) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(type), type, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
type, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::Script, scopeType);
|
||||
}
|
||||
|
||||
|
@ -521,7 +520,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::registerContentForName(
|
|||
// mode, we will figure this out using the scope type and access any enums of the
|
||||
// plain type directly. In indirect mode, we can use enum lookups.
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(attached), attached, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
attached, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
hasObjectModulePrefix
|
||||
? QQmlJSRegisterContent::ObjectAttached
|
||||
: QQmlJSRegisterContent::ScopeAttached, type);
|
||||
|
@ -536,13 +535,13 @@ QQmlJSRegisterContent QQmlJSTypeResolver::registerContentForName(
|
|||
// Store it as QMetaObject.
|
||||
// This only works with namespaces and object types.
|
||||
return QQmlJSRegisterContent::create(
|
||||
metaObjectType(), metaObjectType(), QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
metaObjectType(), QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::MetaType, type);
|
||||
case QQmlJSScope::AccessSemantics::Sequence:
|
||||
case QQmlJSScope::AccessSemantics::Value:
|
||||
if (canAddressValueTypes()) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
metaObjectType(), metaObjectType(), QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
metaObjectType(), QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::MetaType, type);
|
||||
}
|
||||
// Else this is not actually a type reference. You cannot get the metaobject
|
||||
|
@ -746,7 +745,6 @@ QQmlJSRegisterContent QQmlJSTypeResolver::merge(const QQmlJSRegisterContent &a,
|
|||
origins.erase(erase, origins.end());
|
||||
|
||||
return QQmlJSRegisterContent::create(
|
||||
merge(a.storedType(), b.storedType()),
|
||||
origins,
|
||||
merge(containedType(a), containedType(b)),
|
||||
merge(aResultScope, bResultScope),
|
||||
|
@ -988,13 +986,13 @@ QQmlJSRegisterContent QQmlJSTypeResolver::builtinType(const QQmlJSScope::ConstPt
|
|||
{
|
||||
Q_ASSERT(storedType(type) == type);
|
||||
return QQmlJSRegisterContent::create(
|
||||
type, type, QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSRegisterContent::Builtin);
|
||||
type, QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSRegisterContent::Builtin);
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSTypeResolver::globalType(const QQmlJSScope::ConstPtr &type) const
|
||||
{
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(type), type, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
type, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::Unknown);
|
||||
}
|
||||
|
||||
|
@ -1152,8 +1150,8 @@ QQmlJSRegisterContent QQmlJSTypeResolver::scopedType(const QQmlJSRegisterContent
|
|||
{
|
||||
const QQmlJSScope::ConstPtr contained = containedType(scope);
|
||||
if (QQmlJSScope::ConstPtr identified = m_objectsById.scope(name, contained, options)) {
|
||||
return QQmlJSRegisterContent::create(storedType(identified), identified, lookupIndex,
|
||||
QQmlJSRegisterContent::ObjectById, contained);
|
||||
return QQmlJSRegisterContent::create(
|
||||
identified, lookupIndex, QQmlJSRegisterContent::ObjectById, contained);
|
||||
}
|
||||
|
||||
if (QQmlJSScope::ConstPtr base = QQmlJSScope::findCurrentQMLScope(contained)) {
|
||||
|
@ -1170,8 +1168,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::scopedType(const QQmlJSRegisterContent
|
|||
|
||||
prop.setType(resolveParentProperty(name, base, prop.type()));
|
||||
result = QQmlJSRegisterContent::create(
|
||||
storedType(prop.type()), prop,
|
||||
QQmlJSRegisterContent::InvalidLookupIndex, lookupIndex,
|
||||
prop, QQmlJSRegisterContent::InvalidLookupIndex, lookupIndex,
|
||||
scopeContentVariant(mode, false), contained);
|
||||
return true;
|
||||
}
|
||||
|
@ -1187,8 +1184,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::scopedType(const QQmlJSRegisterContent
|
|||
if (methods.isEmpty())
|
||||
return false;
|
||||
result = QQmlJSRegisterContent::create(
|
||||
jsValueType(), methods, scopeContentVariant(mode, true),
|
||||
contained);
|
||||
methods, jsValueType(), scopeContentVariant(mode, true), contained);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1206,13 +1202,12 @@ QQmlJSRegisterContent QQmlJSTypeResolver::scopedType(const QQmlJSRegisterContent
|
|||
|
||||
if (m_jsGlobalObject->hasProperty(name)) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
jsValueType(), m_jsGlobalObject->property(name),
|
||||
QQmlJSRegisterContent::InvalidLookupIndex, lookupIndex,
|
||||
QQmlJSRegisterContent::JavaScriptGlobal, m_jsGlobalObject);
|
||||
m_jsGlobalObject->property(name), QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
lookupIndex, QQmlJSRegisterContent::JavaScriptGlobal, m_jsGlobalObject);
|
||||
} else if (m_jsGlobalObject->hasMethod(name)) {
|
||||
return QQmlJSRegisterContent::create(jsValueType(), m_jsGlobalObject->methods(name),
|
||||
QQmlJSRegisterContent::JavaScriptGlobal,
|
||||
m_jsGlobalObject);
|
||||
return QQmlJSRegisterContent::create(
|
||||
m_jsGlobalObject->methods(name), jsValueType(),
|
||||
QQmlJSRegisterContent::JavaScriptGlobal, m_jsGlobalObject);
|
||||
}
|
||||
|
||||
return {};
|
||||
|
@ -1245,7 +1240,7 @@ bool QQmlJSTypeResolver::checkEnums(const QQmlJSScope::ConstPtr &scope, const QS
|
|||
for (const auto &enumeration : enums) {
|
||||
if ((enumeration.isScoped() || enumeration.isQml()) && enumeration.name() == name) {
|
||||
*result = QQmlJSRegisterContent::create(
|
||||
storedType(enumeration.type()), enumeration, QString(),
|
||||
enumeration, QString(),
|
||||
inExtension ? QQmlJSRegisterContent::ExtensionObjectEnum
|
||||
: QQmlJSRegisterContent::ObjectEnum,
|
||||
scope);
|
||||
|
@ -1254,7 +1249,7 @@ bool QQmlJSTypeResolver::checkEnums(const QQmlJSScope::ConstPtr &scope, const QS
|
|||
|
||||
if (!enumeration.isScoped() && enumeration.hasKey(name)) {
|
||||
*result = QQmlJSRegisterContent::create(
|
||||
storedType(enumeration.type()), enumeration, name,
|
||||
enumeration, name,
|
||||
inExtension ? QQmlJSRegisterContent::ExtensionObjectEnum
|
||||
: QQmlJSRegisterContent::ObjectEnum,
|
||||
scope);
|
||||
|
@ -1523,7 +1518,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::lengthProperty(
|
|||
prop.setType(sizeType());
|
||||
prop.setIsWritable(isWritable);
|
||||
return QQmlJSRegisterContent::create(
|
||||
sizeType(), prop, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
prop, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSRegisterContent::Builtin, scope);
|
||||
}
|
||||
|
||||
|
@ -1544,7 +1539,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
prop.setType(varType());
|
||||
prop.setIsWritable(true);
|
||||
return QQmlJSRegisterContent::create(
|
||||
varType(), prop, baseLookupIndex, resultLookupIndex,
|
||||
prop, baseLookupIndex, resultLookupIndex,
|
||||
QQmlJSRegisterContent::GenericObjectProperty, type);
|
||||
}
|
||||
|
||||
|
@ -1555,7 +1550,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
prop.setType(jsValueType());
|
||||
prop.setIsWritable(true);
|
||||
return QQmlJSRegisterContent::create(
|
||||
jsValueType(), prop, baseLookupIndex, resultLookupIndex,
|
||||
prop, baseLookupIndex, resultLookupIndex,
|
||||
QQmlJSRegisterContent::GenericObjectProperty, type);
|
||||
}
|
||||
|
||||
|
@ -1570,7 +1565,6 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
if (scope->hasOwnProperty(name)) {
|
||||
const auto prop = scope->ownProperty(name);
|
||||
result = QQmlJSRegisterContent::create(
|
||||
storedType(prop.type()),
|
||||
prop, baseLookupIndex, resultLookupIndex,
|
||||
mode == QQmlJSScope::NotExtension
|
||||
? QQmlJSRegisterContent::ObjectProperty
|
||||
|
@ -1582,7 +1576,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
if (scope->hasOwnMethod(name)) {
|
||||
const auto methods = scope->ownMethods(name);
|
||||
result = QQmlJSRegisterContent::create(
|
||||
jsValueType(), methods,
|
||||
methods, jsValueType(),
|
||||
mode == QQmlJSScope::NotExtension
|
||||
? QQmlJSRegisterContent::ObjectMethod
|
||||
: QQmlJSRegisterContent::ExtensionObjectMethod,
|
||||
|
@ -1608,9 +1602,9 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
prop.setType(jsValueType());
|
||||
prop.setIsWritable(!(ownIdentifier.value().isConst));
|
||||
|
||||
return QQmlJSRegisterContent::create(jsValueType(), prop, baseLookupIndex,
|
||||
resultLookupIndex,
|
||||
QQmlJSRegisterContent::JavaScriptObject, scope);
|
||||
return QQmlJSRegisterContent::create(
|
||||
prop, baseLookupIndex, resultLookupIndex,
|
||||
QQmlJSRegisterContent::JavaScriptObject, scope);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1628,8 +1622,8 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
return {};
|
||||
} else {
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(attached), attached, resultLookupIndex,
|
||||
QQmlJSRegisterContent::ObjectAttached, attachedBase);
|
||||
attached, resultLookupIndex, QQmlJSRegisterContent::ObjectAttached,
|
||||
attachedBase);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1671,8 +1665,8 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
const auto enumeration = type.enumeration();
|
||||
if (!type.enumMember().isEmpty() || !enumeration.hasKey(name))
|
||||
return {};
|
||||
return QQmlJSRegisterContent::create(storedType(enumeration.type()), enumeration, name,
|
||||
QQmlJSRegisterContent::ObjectEnum, type.scopeType());
|
||||
return QQmlJSRegisterContent::create(
|
||||
enumeration, name, QQmlJSRegisterContent::ObjectEnum, type.scopeType());
|
||||
}
|
||||
if (type.isMethod()) {
|
||||
QQmlJSMetaProperty prop;
|
||||
|
@ -1681,7 +1675,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::memberType(
|
|||
prop.setType(jsValueType());
|
||||
prop.setIsWritable(true);
|
||||
return QQmlJSRegisterContent::create(
|
||||
jsValueType(), prop, QQmlJSRegisterContent::InvalidLookupIndex, lookupIndex,
|
||||
prop, QQmlJSRegisterContent::InvalidLookupIndex, lookupIndex,
|
||||
QQmlJSRegisterContent::GenericObjectProperty, jsValueType());
|
||||
}
|
||||
if (type.isImportNamespace()) {
|
||||
|
@ -1770,7 +1764,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::valueType(const QQmlJSRegisterContent
|
|||
property.setType(value);
|
||||
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(value), property, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
property, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSRegisterContent::ListValue, scope);
|
||||
}
|
||||
|
||||
|
@ -1781,7 +1775,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::returnType(
|
|||
Q_ASSERT(variant == QQmlJSRegisterContent::MethodReturnValue
|
||||
|| variant == QQmlJSRegisterContent::JavaScriptReturnValue);
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(type), type, QQmlJSRegisterContent::InvalidLookupIndex, variant, scope);
|
||||
type, QQmlJSRegisterContent::InvalidLookupIndex, variant, scope);
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSTypeResolver::iteratorPointer(
|
||||
|
@ -1803,7 +1797,7 @@ QQmlJSRegisterContent QQmlJSTypeResolver::iteratorPointer(
|
|||
prop.setTypeName(iteratorPointer->internalName());
|
||||
prop.setType(iteratorPointer);
|
||||
return QQmlJSRegisterContent::create(
|
||||
storedType(iteratorPointer), prop, lookupIndex,
|
||||
prop, lookupIndex,
|
||||
QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSRegisterContent::ListIterator,
|
||||
listContained);
|
||||
}
|
||||
|
@ -1868,20 +1862,20 @@ QQmlJSRegisterContent QQmlJSTypeResolver::convert(
|
|||
{
|
||||
if (from.isConversion()) {
|
||||
return QQmlJSRegisterContent::create(
|
||||
to.storedType(), from.conversionOrigins(), containedType(to),
|
||||
from.conversionOrigins(), containedType(to),
|
||||
to.scopeType() ? to.scopeType() : from.conversionResultScope(),
|
||||
from.variant(), from.scopeType());
|
||||
}
|
||||
|
||||
return QQmlJSRegisterContent::create(
|
||||
to.storedType(), QList<QQmlJSScope::ConstPtr>{containedType(from)},
|
||||
QList<QQmlJSScope::ConstPtr>{containedType(from)},
|
||||
containedType(to), to.scopeType(), from.variant(), from.scopeType());
|
||||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSTypeResolver::cast(
|
||||
const QQmlJSRegisterContent &from, const QQmlJSScope::ConstPtr &to) const
|
||||
{
|
||||
return from.castTo(to).storedIn(storedType(to));
|
||||
return from.castTo(to);
|
||||
}
|
||||
|
||||
QQmlJSScope::ConstPtr QQmlJSTypeResolver::comparableType(const QQmlJSScope::ConstPtr &type) const
|
||||
|
|
|
@ -1374,8 +1374,7 @@ void TestQmllint::compilerWarnings_data()
|
|||
|
||||
QTest::newRow("shadowable")
|
||||
<< QStringLiteral("shadowable.qml")
|
||||
<< Result { { Message {QStringLiteral(
|
||||
"with type NotSoSimple (stored as QQuickItem) can be shadowed") } } }
|
||||
<< Result { { Message {QStringLiteral("with type NotSoSimple can be shadowed") } } }
|
||||
<< true;
|
||||
QTest::newRow("tooFewParameters")
|
||||
<< QStringLiteral("tooFewParams.qml")
|
||||
|
@ -1411,20 +1410,20 @@ void TestQmllint::compilerWarnings_data()
|
|||
<< QStringLiteral("returnTypeAnnotation_component.qml")
|
||||
<< Result{ { { "Could not compile function comp: function without return type "
|
||||
"annotation returns (component in" },
|
||||
{ "returnTypeAnnotation_component.qml)::c with type Comp (stored as "
|
||||
"QQuickItem). This may prevent proper compilation to Cpp." } } }
|
||||
{ "returnTypeAnnotation_component.qml)::c with type Comp. "
|
||||
"This may prevent proper compilation to Cpp." } } }
|
||||
<< true;
|
||||
QTest::newRow("returnTypeAnnotation-enum")
|
||||
<< QStringLiteral("returnTypeAnnotation_enum.qml")
|
||||
<< Result{ { { "Could not compile function enumeration: function without return type "
|
||||
"annotation returns QQuickText::HAlignment::AlignRight (stored as int). "
|
||||
"annotation returns QQuickText::HAlignment::AlignRight. "
|
||||
"This may prevent proper compilation to Cpp." } } }
|
||||
<< true;
|
||||
QTest::newRow("returnTypeAnnotation-method")
|
||||
<< QStringLiteral("returnTypeAnnotation_method.qml")
|
||||
<< Result{ { { "Could not compile function method: function without return type "
|
||||
"annotation returns (component in " }, // Don't check the build folder path
|
||||
{ "returnTypeAnnotation_method.qml)::f(...) (stored as QJSValue). This may "
|
||||
{ "returnTypeAnnotation_method.qml)::f(...). This may "
|
||||
"prevent proper compilation to Cpp." } } }
|
||||
<< true;
|
||||
QTest::newRow("returnTypeAnnotation-property")
|
||||
|
|
|
@ -355,9 +355,9 @@ void tst_qqmljsscope::descriptiveNameOfNull()
|
|||
property.setPropertyName(u"foo"_s);
|
||||
property.setTypeName(u"baz"_s);
|
||||
QQmlJSRegisterContent unscoped = QQmlJSRegisterContent::create(
|
||||
stored, property, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
property, QQmlJSRegisterContent::InvalidLookupIndex,
|
||||
QQmlJSRegisterContent::InvalidLookupIndex, QQmlJSRegisterContent::ScopeProperty,
|
||||
QQmlJSScope::ConstPtr());
|
||||
QQmlJSScope::ConstPtr()).storedIn(stored);
|
||||
QCOMPARE(unscoped.descriptiveName(), u"(invalid type)::foo with type baz (stored as bar)"_s);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue