QmlCompiler: Inline translation methods
We hardcode them into QQmlJSTypePropagator and QQmlJSCodegenerator for now. This is OK for builtins. Task-number: QTBUG-101387 Change-Id: Ifab46083b3a782f009859ce969c283d5bb2b4e8b Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
This commit is contained in:
parent
1b6069798a
commit
23fdccf7f3
|
@ -19,6 +19,7 @@
|
|||
#include <private/qv4qobjectwrapper_p.h>
|
||||
#include <private/qv4identifiertable_p.h>
|
||||
#include <private/qv4errorobject_p.h>
|
||||
#include <private/qqmlbuiltinfunctions_p.h>
|
||||
#include <private/qqmlfinalizer_p.h>
|
||||
|
||||
#include <QtCore/qmutex.h>
|
||||
|
@ -763,18 +764,26 @@ void AOTCompiledContext::setReturnValueUndefined() const
|
|||
}
|
||||
}
|
||||
|
||||
static void captureFallbackProperty(
|
||||
QObject *object, int coreIndex, int notifyIndex, bool isConstant,
|
||||
QQmlContextData *qmlContext)
|
||||
static QQmlPropertyCapture *propertyCapture(const QQmlContextData *qmlContext)
|
||||
{
|
||||
if (!qmlContext || isConstant)
|
||||
return;
|
||||
if (!qmlContext)
|
||||
return nullptr;
|
||||
|
||||
QQmlEngine *engine = qmlContext->engine();
|
||||
Q_ASSERT(engine);
|
||||
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
|
||||
Q_ASSERT(ep);
|
||||
if (QQmlPropertyCapture *capture = ep->propertyCapture)
|
||||
return ep->propertyCapture;
|
||||
}
|
||||
|
||||
static void captureFallbackProperty(
|
||||
QObject *object, int coreIndex, int notifyIndex, bool isConstant,
|
||||
const QQmlContextData *qmlContext)
|
||||
{
|
||||
if (isConstant)
|
||||
return;
|
||||
|
||||
if (QQmlPropertyCapture *capture = propertyCapture(qmlContext))
|
||||
capture->captureProperty(object, coreIndex, notifyIndex);
|
||||
}
|
||||
|
||||
|
@ -782,14 +791,10 @@ static void captureObjectProperty(
|
|||
QObject *object, const QQmlPropertyCache *propertyCache,
|
||||
const QQmlPropertyData *property, QQmlContextData *qmlContext)
|
||||
{
|
||||
if (!qmlContext || property->isConstant())
|
||||
if (property->isConstant())
|
||||
return;
|
||||
|
||||
QQmlEngine *engine = qmlContext->engine();
|
||||
Q_ASSERT(engine);
|
||||
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
|
||||
Q_ASSERT(ep);
|
||||
if (QQmlPropertyCapture *capture = ep->propertyCapture)
|
||||
if (QQmlPropertyCapture *capture = propertyCapture(qmlContext))
|
||||
capture->captureProperty(object, propertyCache, property);
|
||||
}
|
||||
|
||||
|
@ -1059,6 +1064,21 @@ bool AOTCompiledContext::captureQmlContextPropertyLookup(uint index) const
|
|||
return false;
|
||||
}
|
||||
|
||||
void AOTCompiledContext::captureTranslation() const
|
||||
{
|
||||
if (QQmlPropertyCapture *capture = propertyCapture(qmlContext))
|
||||
capture->captureTranslation();
|
||||
}
|
||||
|
||||
QString AOTCompiledContext::translationContext() const
|
||||
{
|
||||
#if QT_CONFIG(translation)
|
||||
return QV4::GlobalExtensions::currentTranslationContext(engine->handle());
|
||||
#else
|
||||
return QString();
|
||||
#endif
|
||||
}
|
||||
|
||||
QMetaType AOTCompiledContext::lookupResultMetaType(uint index) const
|
||||
{
|
||||
QV4::Lookup *l = compilationUnit->runtimeLookups + index;
|
||||
|
|
|
@ -1942,6 +1942,42 @@ ReturnedValue GlobalExtensions::method_qsTranslateNoOp(const FunctionObject *b,
|
|||
return argv[1].asReturnedValue();
|
||||
}
|
||||
|
||||
QString GlobalExtensions::currentTranslationContext(ExecutionEngine *engine)
|
||||
{
|
||||
QString context;
|
||||
CppStackFrame *frame = engine->currentStackFrame;
|
||||
|
||||
// The first non-empty source URL in the call stack determines the translation context.
|
||||
while (frame && context.isEmpty()) {
|
||||
if (CompiledData::CompilationUnitBase *baseUnit = frame->v4Function->compilationUnit) {
|
||||
const auto *unit = static_cast<const CompiledData::CompilationUnit *>(baseUnit);
|
||||
QString fileName = unit->fileName();
|
||||
QUrl url(unit->fileName());
|
||||
if (url.isValid() && url.isRelative()) {
|
||||
context = url.fileName();
|
||||
} else {
|
||||
context = QQmlFile::urlToLocalFileOrQrc(fileName);
|
||||
if (context.isEmpty() && fileName.startsWith(QLatin1String(":/")))
|
||||
context = fileName;
|
||||
}
|
||||
context = QFileInfo(context).baseName();
|
||||
}
|
||||
frame = frame->parentFrame();
|
||||
}
|
||||
|
||||
if (context.isEmpty()) {
|
||||
if (QQmlRefPointer<QQmlContextData> ctxt = engine->callingQmlContext()) {
|
||||
QString path = ctxt->urlString();
|
||||
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
|
||||
int lastDot = path.lastIndexOf(QLatin1Char('.'));
|
||||
int length = lastDot - (lastSlash + 1);
|
||||
context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
|
||||
}
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
/*!
|
||||
\qmlmethod string Qt::qsTr(string sourceText, string disambiguation, int n)
|
||||
|
||||
|
@ -1971,43 +2007,10 @@ ReturnedValue GlobalExtensions::method_qsTr(const FunctionObject *b, const Value
|
|||
if ((argc > 2) && !argv[2].isNumber())
|
||||
THROW_GENERIC_ERROR("qsTr(): third argument (n) must be a number");
|
||||
|
||||
QString context;
|
||||
CppStackFrame *frame = scope.engine->currentStackFrame;
|
||||
// The first non-empty source URL in the call stack determines the translation context.
|
||||
while (frame && context.isEmpty()) {
|
||||
if (CompiledData::CompilationUnitBase *baseUnit = frame->v4Function->compilationUnit) {
|
||||
const auto *unit = static_cast<const CompiledData::CompilationUnit *>(baseUnit);
|
||||
QString fileName = unit->fileName();
|
||||
QUrl url(unit->fileName());
|
||||
if (url.isValid() && url.isRelative()) {
|
||||
context = url.fileName();
|
||||
} else {
|
||||
context = QQmlFile::urlToLocalFileOrQrc(fileName);
|
||||
if (context.isEmpty() && fileName.startsWith(QLatin1String(":/")))
|
||||
context = fileName;
|
||||
}
|
||||
context = QFileInfo(context).baseName();
|
||||
}
|
||||
frame = frame->parentFrame();
|
||||
}
|
||||
|
||||
if (context.isEmpty()) {
|
||||
if (QQmlRefPointer<QQmlContextData> ctxt = scope.engine->callingQmlContext()) {
|
||||
QString path = ctxt->urlString();
|
||||
int lastSlash = path.lastIndexOf(QLatin1Char('/'));
|
||||
int lastDot = path.lastIndexOf(QLatin1Char('.'));
|
||||
int length = lastDot - (lastSlash + 1);
|
||||
context = (lastSlash > -1) ? path.mid(lastSlash + 1, (length > -1) ? length : -1) : QString();
|
||||
}
|
||||
}
|
||||
|
||||
QString text = argv[0].toQStringNoThrow();
|
||||
QString comment;
|
||||
if (argc > 1)
|
||||
comment = argv[1].toQStringNoThrow();
|
||||
int n = -1;
|
||||
if (argc > 2)
|
||||
n = argv[2].toInt32();
|
||||
const QString context = currentTranslationContext(scope.engine);
|
||||
const QString text = argv[0].toQStringNoThrow();
|
||||
const QString comment = argc > 1 ? argv[1].toQStringNoThrow() : QString();
|
||||
const int n = argc > 2 ? argv[2].toInt32() : -1;
|
||||
|
||||
if (QQmlEnginePrivate *ep = (scope.engine->qmlEngine() ? QQmlEnginePrivate::get(scope.engine->qmlEngine()) : nullptr))
|
||||
if (ep->propertyCapture)
|
||||
|
|
|
@ -209,6 +209,7 @@ struct Q_QML_PRIVATE_EXPORT GlobalExtensions {
|
|||
static void init(Object *globalObject, QJSEngine::Extensions extensions);
|
||||
|
||||
#if QT_CONFIG(translation)
|
||||
static QString currentTranslationContext(ExecutionEngine *engine);
|
||||
static ReturnedValue method_qsTranslate(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
|
||||
static ReturnedValue method_qsTranslateNoOp(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
|
||||
static ReturnedValue method_qsTr(const FunctionObject *b, const Value *thisObject, const Value *argv, int argc);
|
||||
|
|
|
@ -600,6 +600,8 @@ namespace QQmlPrivate
|
|||
// Run QQmlPropertyCapture::captureProperty() without retrieving the value.
|
||||
bool captureLookup(uint index, QObject *object) const;
|
||||
bool captureQmlContextPropertyLookup(uint index) const;
|
||||
void captureTranslation() const;
|
||||
QString translationContext() const;
|
||||
QMetaType lookupResultMetaType(uint index) const;
|
||||
void storeNameSloppy(uint nameIndex, void *value, QMetaType type) const;
|
||||
QJSValue javaScriptGlobalProperty(uint nameIndex) const;
|
||||
|
|
|
@ -1166,6 +1166,81 @@ void QQmlJSCodeGenerator::generate_CallProperty(int nameIndex, int baseReg, int
|
|||
reject(u"CallProperty"_s);
|
||||
}
|
||||
|
||||
bool QQmlJSCodeGenerator::inlineTranslateMethod(const QString &name, int argc, int argv)
|
||||
{
|
||||
addInclude(u"qcoreapplication.h"_s);
|
||||
|
||||
const auto arg = [&](int i, const QQmlJSScope::ConstPtr &type) {
|
||||
Q_ASSERT(i < argc);
|
||||
return conversion(registerType(argv + i).storedType(), type, registerVariable(argv + i));
|
||||
};
|
||||
|
||||
const auto stringArg = [&](int i) {
|
||||
return i < argc
|
||||
? (arg(i, m_typeResolver->stringType()) + u".toUtf8().constData()"_s)
|
||||
: u"\"\""_s;
|
||||
};
|
||||
|
||||
const auto intArg = [&](int i) {
|
||||
return i < argc ? arg(i, m_typeResolver->intType()) : u"-1"_s;
|
||||
};
|
||||
|
||||
const auto stringRet = [&](const QString &expression) {
|
||||
return conversion(
|
||||
m_typeResolver->stringType(), m_state.accumulatorOut().storedType(), expression);
|
||||
};
|
||||
|
||||
const auto capture = [&]() {
|
||||
m_body += u"aotContext->captureTranslation();\n"_s;
|
||||
};
|
||||
|
||||
if (name == u"QT_TRID_NOOP"_s || name == u"QT_TR_NOOP"_s) {
|
||||
Q_ASSERT(argc > 0);
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ stringRet(arg(0, m_typeResolver->stringType())) + u";\n"_s;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == u"QT_TRANSLATE_NOOP"_s) {
|
||||
Q_ASSERT(argc > 1);
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ stringRet(arg(1, m_typeResolver->stringType())) + u";\n"_s;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == u"qsTrId"_s) {
|
||||
capture();
|
||||
// We inline qtTrId() here because in the !QT_CONFIG(translation) case it's unavailable.
|
||||
// QCoreApplication::translate() is always available in some primitive form.
|
||||
// Also, this saves a function call.
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ stringRet(u"QCoreApplication::translate(nullptr, "_s + stringArg(0) +
|
||||
u", nullptr, "_s + intArg(1) + u")"_s) + u";\n"_s;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == u"qsTr"_s) {
|
||||
capture();
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ stringRet(u"QCoreApplication::translate("_s
|
||||
+ u"aotContext->translationContext().toUtf8().constData(), "_s
|
||||
+ stringArg(0) + u", "_s + stringArg(1) + u", "_s
|
||||
+ intArg(2) + u")"_s) + u";\n"_s;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (name == u"qsTranslate"_s) {
|
||||
capture();
|
||||
m_body += m_state.accumulatorVariableOut + u" = "_s
|
||||
+ stringRet(u"QCoreApplication::translate("_s
|
||||
+ stringArg(0) + u", "_s + stringArg(1) + u", "_s
|
||||
+ stringArg(2) + u", "_s + intArg(3) + u")"_s) + u";\n"_s;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool QQmlJSCodeGenerator::inlineMathMethod(const QString &name, int argc, int argv)
|
||||
{
|
||||
addInclude(u"cmath"_s);
|
||||
|
@ -1372,6 +1447,14 @@ void QQmlJSCodeGenerator::generate_CallQmlContextPropertyLookup(int index, int a
|
|||
if (m_state.accumulatorOut().variant() == QQmlJSRegisterContent::JavaScriptReturnValue)
|
||||
reject(u"call to untyped JavaScript function"_s);
|
||||
|
||||
if (m_typeResolver->equals(m_state.accumulatorOut().scopeType(),
|
||||
m_typeResolver->jsGlobalObject())) {
|
||||
const QString name = m_jsUnitGenerator->stringForIndex(
|
||||
m_jsUnitGenerator->lookupNameIndex(index));
|
||||
if (inlineTranslateMethod(name, argc, argv))
|
||||
return;
|
||||
}
|
||||
|
||||
AccumulatorConverter registers(this);
|
||||
|
||||
const QString indexString = QString::number(index);
|
||||
|
|
|
@ -261,7 +261,9 @@ private:
|
|||
QString argumentsList(int argc, int argv, QString *outVar);
|
||||
QString castTargetName(const QQmlJSScope::ConstPtr &type) const;
|
||||
|
||||
bool inlineTranslateMethod(const QString &name, int argc, int argv);
|
||||
bool inlineMathMethod(const QString &name, int argc, int argv);
|
||||
|
||||
QQmlJSScope::ConstPtr mathObject() const
|
||||
{
|
||||
using namespace Qt::StringLiterals;
|
||||
|
|
|
@ -1027,7 +1027,7 @@ void QQmlJSTypePropagator::generate_CallProperty(int nameIndex, int base, int ar
|
|||
}
|
||||
|
||||
addReadRegister(base, callBase);
|
||||
propagateCall(member.method(), argc, argv);
|
||||
propagateCall(member.method(), argc, argv, member.scopeType());
|
||||
}
|
||||
|
||||
QQmlJSMetaMethod QQmlJSTypePropagator::bestMatchForCall(const QList<QQmlJSMetaMethod> &methods,
|
||||
|
@ -1149,7 +1149,9 @@ void QQmlJSTypePropagator::addReadRegister(int index, const QQmlJSRegisterConten
|
|||
m_state.addReadRegister(index, m_typeResolver->convert(m_state.registers[index], convertTo));
|
||||
}
|
||||
|
||||
void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods, int argc, int argv)
|
||||
void QQmlJSTypePropagator::propagateCall(
|
||||
const QList<QQmlJSMetaMethod> &methods, int argc, int argv,
|
||||
const QQmlJSScope::ConstPtr &scope)
|
||||
{
|
||||
QStringList errors;
|
||||
const QQmlJSMetaMethod match = bestMatchForCall(methods, argc, argv, &errors);
|
||||
|
@ -1167,9 +1169,11 @@ void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods,
|
|||
? m_typeResolver->jsValueType()
|
||||
: QQmlJSScope::ConstPtr(match.returnType());
|
||||
setAccumulator(m_typeResolver->returnType(
|
||||
returnType ? QQmlJSScope::ConstPtr(returnType) : m_typeResolver->voidType(),
|
||||
match.isJavaScriptFunction() ? QQmlJSRegisterContent::JavaScriptReturnValue
|
||||
: QQmlJSRegisterContent::MethodReturnValue));
|
||||
returnType ? QQmlJSScope::ConstPtr(returnType) : m_typeResolver->voidType(),
|
||||
match.isJavaScriptFunction()
|
||||
? QQmlJSRegisterContent::JavaScriptReturnValue
|
||||
: QQmlJSRegisterContent::MethodReturnValue,
|
||||
scope));
|
||||
if (!m_state.accumulatorOut().isValid())
|
||||
setError(u"Cannot store return type of method %1()."_s.arg(match.methodName()));
|
||||
|
||||
|
@ -1189,6 +1193,114 @@ void QQmlJSTypePropagator::propagateCall(const QList<QQmlJSMetaMethod> &methods,
|
|||
}
|
||||
}
|
||||
|
||||
bool QQmlJSTypePropagator::propagateTranslationMethod(
|
||||
const QList<QQmlJSMetaMethod> &methods, int argc, int argv)
|
||||
{
|
||||
if (methods.length() != 1)
|
||||
return false;
|
||||
|
||||
const QQmlJSMetaMethod method = methods.front();
|
||||
const QQmlJSRegisterContent intType
|
||||
= m_typeResolver->globalType(m_typeResolver->intType());
|
||||
const QQmlJSRegisterContent stringType
|
||||
= m_typeResolver->globalType(m_typeResolver->stringType());
|
||||
const QQmlJSRegisterContent returnType
|
||||
= m_typeResolver->returnType(
|
||||
m_typeResolver->stringType(), QQmlJSRegisterContent::MethodReturnValue,
|
||||
m_typeResolver->jsGlobalObject());
|
||||
|
||||
if (method.methodName() == u"qsTranslate"_s) {
|
||||
switch (argc) {
|
||||
case 4:
|
||||
addReadRegister(argv + 3, intType); // n
|
||||
Q_FALLTHROUGH();
|
||||
case 3:
|
||||
addReadRegister(argv + 2, stringType); // disambiguation
|
||||
Q_FALLTHROUGH();
|
||||
case 2:
|
||||
addReadRegister(argv + 1, stringType); // sourceText
|
||||
addReadRegister(argv, stringType); // context
|
||||
setAccumulator(returnType);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (method.methodName() == u"QT_TRANSLATE_NOOP"_s) {
|
||||
switch (argc) {
|
||||
case 3:
|
||||
addReadRegister(argv + 2, stringType); // disambiguation
|
||||
Q_FALLTHROUGH();
|
||||
case 2:
|
||||
addReadRegister(argv + 1, stringType); // sourceText
|
||||
addReadRegister(argv, stringType); // context
|
||||
setAccumulator(returnType);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (method.methodName() == u"qsTr"_s) {
|
||||
switch (argc) {
|
||||
case 3:
|
||||
addReadRegister(argv + 2, intType); // n
|
||||
Q_FALLTHROUGH();
|
||||
case 2:
|
||||
addReadRegister(argv + 1, stringType); // disambiguation
|
||||
Q_FALLTHROUGH();
|
||||
case 1:
|
||||
addReadRegister(argv, stringType); // sourceText
|
||||
setAccumulator(returnType);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (method.methodName() == u"QT_TR_NOOP"_s) {
|
||||
switch (argc) {
|
||||
case 2:
|
||||
addReadRegister(argv + 1, stringType); // disambiguation
|
||||
Q_FALLTHROUGH();
|
||||
case 1:
|
||||
addReadRegister(argv, stringType); // sourceText
|
||||
setAccumulator(returnType);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (method.methodName() == u"qsTrId"_s) {
|
||||
switch (argc) {
|
||||
case 2:
|
||||
addReadRegister(argv + 1, intType); // n
|
||||
Q_FALLTHROUGH();
|
||||
case 1:
|
||||
addReadRegister(argv, stringType); // id
|
||||
setAccumulator(returnType);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (method.methodName() == u"QT_TRID_NOOP"_s) {
|
||||
switch (argc) {
|
||||
case 1:
|
||||
addReadRegister(argv, stringType); // id
|
||||
setAccumulator(returnType);
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void QQmlJSTypePropagator::generate_CallPropertyLookup(int lookupIndex, int base, int argc,
|
||||
int argv)
|
||||
{
|
||||
|
@ -1224,8 +1336,13 @@ void QQmlJSTypePropagator::propagateScopeLookupCall(const QString &functionName,
|
|||
= m_typeResolver->scopedType(m_function->qmlScope, functionName);
|
||||
if (resolvedContent.isMethod()) {
|
||||
const auto methods = resolvedContent.method();
|
||||
if (resolvedContent.variant() == QQmlJSRegisterContent::JavaScriptGlobal) {
|
||||
if (propagateTranslationMethod(methods, argc, argv))
|
||||
return;
|
||||
}
|
||||
|
||||
if (!methods.isEmpty()) {
|
||||
propagateCall(methods, argc, argv);
|
||||
propagateCall(methods, argc, argv, resolvedContent.scopeType());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,10 @@ private:
|
|||
QQmlJS::SourceLocation getCurrentBindingSourceLocation() const;
|
||||
|
||||
QQmlJSRegisterContent propagateBinaryOperation(QSOperator::Op op, int lhs);
|
||||
void propagateCall(const QList<QQmlJSMetaMethod> &methods, int argc, int argv);
|
||||
void propagateCall(
|
||||
const QList<QQmlJSMetaMethod> &methods, int argc, int argv,
|
||||
const QQmlJSScope::ConstPtr &scope);
|
||||
bool propagateTranslationMethod(const QList<QQmlJSMetaMethod> &methods, int argc, int argv);
|
||||
void propagatePropertyLookup(const QString &name);
|
||||
void propagateScopeLookupCall(const QString &functionName, int argc, int argv);
|
||||
void saveRegisterStateForJump(int offset);
|
||||
|
|
|
@ -1200,11 +1200,12 @@ QQmlJSRegisterContent QQmlJSTypeResolver::valueType(const QQmlJSRegisterContent
|
|||
}
|
||||
|
||||
QQmlJSRegisterContent QQmlJSTypeResolver::returnType(
|
||||
const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant) const
|
||||
const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope) const
|
||||
{
|
||||
Q_ASSERT(variant == QQmlJSRegisterContent::MethodReturnValue
|
||||
|| variant == QQmlJSRegisterContent::JavaScriptReturnValue);
|
||||
return QQmlJSRegisterContent::create(storedType(type), type, variant);
|
||||
return QQmlJSRegisterContent::create(storedType(type), type, variant, scope);
|
||||
}
|
||||
|
||||
bool QQmlJSTypeResolver::registerIsStoredIn(
|
||||
|
|
|
@ -99,8 +99,9 @@ public:
|
|||
QQmlJSRegisterContent scopedType(const QQmlJSScope::ConstPtr &scope, const QString &name) const;
|
||||
QQmlJSRegisterContent memberType(const QQmlJSRegisterContent &type, const QString &name) const;
|
||||
QQmlJSRegisterContent valueType(const QQmlJSRegisterContent &list) const;
|
||||
QQmlJSRegisterContent returnType(const QQmlJSScope::ConstPtr &type,
|
||||
QQmlJSRegisterContent::ContentVariant variant) const;
|
||||
QQmlJSRegisterContent returnType(
|
||||
const QQmlJSScope::ConstPtr &type, QQmlJSRegisterContent::ContentVariant variant,
|
||||
const QQmlJSScope::ConstPtr &scope) const;
|
||||
|
||||
bool registerIsStoredIn(const QQmlJSRegisterContent ®,
|
||||
const QQmlJSScope::ConstPtr &type) const;
|
||||
|
|
|
@ -136,6 +136,7 @@ set(qml_files
|
|||
themergood.qml
|
||||
throwObjectName.qml
|
||||
toString.qml
|
||||
translation.qml
|
||||
typePropertyClash.qml
|
||||
typedArray.qml
|
||||
undefinedResets.qml
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
pragma Strict
|
||||
import QtQml
|
||||
|
||||
QtObject {
|
||||
// Force the engine to generate script bindings by appending an empty string to each one.
|
||||
|
||||
property string translate2: qsTranslate("c", "s") + ""
|
||||
property string translate3: qsTranslate("c", "s", "d") + ""
|
||||
property string translate4: qsTranslate("c", "s", "d", 4) + ""
|
||||
|
||||
property string translateNoop2: QT_TRANSLATE_NOOP("c", "s") + ""
|
||||
property string translateNoop3: QT_TRANSLATE_NOOP("c", "s", "d") + ""
|
||||
|
||||
property string tr1: qsTr("s") + ""
|
||||
property string tr2: qsTr("s", "d") + ""
|
||||
property string tr3: qsTr("s", "d", 4) + ""
|
||||
|
||||
property string trNoop1: QT_TR_NOOP("s") + ""
|
||||
property string trNoop2: QT_TR_NOOP("s", "d") + ""
|
||||
|
||||
property string trId1: qsTrId("s") + ""
|
||||
property string trId2: qsTrId("s", 4) + ""
|
||||
|
||||
property string trIdNoop1: QT_TRID_NOOP("s") + ""
|
||||
}
|
|
@ -123,6 +123,7 @@ private slots:
|
|||
void objectToString();
|
||||
void throwObjectName();
|
||||
void javaScriptArgument();
|
||||
void translation();
|
||||
};
|
||||
|
||||
void tst_QmlCppCodegen::simpleBinding()
|
||||
|
@ -2242,6 +2243,33 @@ void tst_QmlCppCodegen::javaScriptArgument()
|
|||
QCOMPARE(o->property("d").toString(), u"9"_qs);
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::translation()
|
||||
{
|
||||
QQmlEngine engine;
|
||||
QQmlComponent c(&engine, QUrl(u"qrc:/qt/qml/TestTypes/translation.qml"_s));
|
||||
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
|
||||
QScopedPointer<QObject> o(c.create());
|
||||
|
||||
QCOMPARE(o->property("translate2"), u"s"_s);
|
||||
QCOMPARE(o->property("translate3"), u"s"_s);
|
||||
QCOMPARE(o->property("translate4"), u"s"_s);
|
||||
|
||||
QCOMPARE(o->property("translateNoop2"), u"s"_s);
|
||||
QCOMPARE(o->property("translateNoop3"), u"s"_s);
|
||||
|
||||
QCOMPARE(o->property("tr1"), u"s"_s);
|
||||
QCOMPARE(o->property("tr2"), u"s"_s);
|
||||
QCOMPARE(o->property("tr3"), u"s"_s);
|
||||
|
||||
QCOMPARE(o->property("trNoop1"), u"s"_s);
|
||||
QCOMPARE(o->property("trNoop2"), u"s"_s);
|
||||
|
||||
QCOMPARE(o->property("trId1"), u"s"_s);
|
||||
QCOMPARE(o->property("trId2"), u"s"_s);
|
||||
|
||||
QCOMPARE(o->property("trIdNoop1"), u"s"_s);
|
||||
}
|
||||
|
||||
void tst_QmlCppCodegen::runInterpreted()
|
||||
{
|
||||
#ifdef Q_OS_ANDROID
|
||||
|
|
Loading…
Reference in New Issue