1/****************************************************************************
2**
3** Copyright (C) 2016 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28#include "testtypes.h"
29
30#include <private/qv4qmlcontext_p.h>
31
32static QObject *myTypeObjectSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
33{
34 Q_UNUSED(engine)
35 Q_UNUSED(scriptEngine)
36
37 return new MyTypeObject();
38}
39
40static QJSValue myQJSValueQObjectSingleton(QQmlEngine *engine, QJSEngine *scriptEngine)
41{
42 Q_UNUSED(engine)
43
44 QJSValue value = scriptEngine->newQObject(object: new MyTypeObject());
45 return value;
46}
47
48void registerTypes()
49{
50 qmlRegisterInterface<MyInterface>(typeName: "MyInterface");
51 qmlRegisterType<MyQmlObject>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyQmlObject");
52 qmlRegisterType<MyTypeObject>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyTypeObject");
53 qmlRegisterType<MyContainer>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyContainer");
54 qmlRegisterType<MyPropertyValueSource>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyPropertyValueSource");
55 qmlRegisterType<MyDotPropertyObject>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyDotPropertyObject");
56 qmlRegisterType<MyNamespace::MyNamespacedType>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyNamespacedType");
57 qmlRegisterType<MyNamespace::MySecondNamespacedType>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MySecondNamespacedType");
58 qmlRegisterUncreatableMetaObject(staticMetaObject: MyNamespace::staticMetaObject, uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyNamespace", reason: "Access to enums & flags only");
59 qmlRegisterType<MyParserStatus>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyParserStatus");
60 qmlRegisterAnonymousType<MyGroupedObject>(uri: "Test", versionMajor: 1);
61 qmlRegisterType<MyRevisionedClass>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyRevisionedClass");
62 qmlRegisterType<MyRevisionedClass,1>(uri: "Test",versionMajor: 1,versionMinor: 1,qmlName: "MyRevisionedClass");
63 qmlRegisterType<MyRevisionedIllegalOverload>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyRevisionedIllegalOverload");
64 qmlRegisterType<MyRevisionedLegalOverload>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyRevisionedLegalOverload");
65 qmlRegisterType<SomethingKnown>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "SomethingKnown");
66
67 // Register the uncreatable base class
68 qmlRegisterRevision<MyRevisionedBaseClassRegistered,1>(uri: "Test",versionMajor: 1,versionMinor: 1);
69 // MyRevisionedSubclass 1.0 uses MyRevisionedClass revision 0
70 qmlRegisterType<MyRevisionedSubclass>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyRevisionedSubclass");
71 // MyRevisionedSubclass 1.1 uses MyRevisionedClass revision 1
72 qmlRegisterType<MyRevisionedSubclass,1>(uri: "Test",versionMajor: 1,versionMinor: 1,qmlName: "MyRevisionedSubclass");
73
74 // Only version 1.0, but its super class is registered in version 1.1 also
75 qmlRegisterType<MySubclass>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MySubclass");
76
77 qmlRegisterCustomType<MyCustomParserType>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyCustomParserType", parser: new MyCustomParserTypeParser);
78 qmlRegisterCustomType<MyCustomParserType>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyCustomParserWithEnumType", parser: new EnumSupportingCustomParser);
79
80 qmlRegisterTypeNotAvailable(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "UnavailableType", message: "UnavailableType is unavailable for testing");
81
82 qmlRegisterType<MyQmlObject>(uri: "Test.Version",versionMajor: 1,versionMinor: 0,qmlName: "MyQmlObject");
83 qmlRegisterType<MyTypeObject>(uri: "Test.Version",versionMajor: 1,versionMinor: 0,qmlName: "MyTypeObject");
84 qmlRegisterType<MyTypeObject>(uri: "Test.Version",versionMajor: 2,versionMinor: 0,qmlName: "MyTypeObject");
85
86 qmlRegisterType<MyVersion2Class>(uri: "Test.VersionOrder", versionMajor: 2,versionMinor: 0, qmlName: "MyQmlObject");
87 qmlRegisterType<MyQmlObject>(uri: "Test.VersionOrder", versionMajor: 1,versionMinor: 0, qmlName: "MyQmlObject");
88
89 qmlRegisterType<MyEnum1Class>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyEnum1Class");
90 qmlRegisterType<MyEnum2Class>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyEnum2Class");
91 qmlRegisterType<MyEnumDerivedClass>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyEnumDerivedClass");
92
93 qmlRegisterType<MyReceiversTestObject>(uri: "Test",versionMajor: 1,versionMinor: 0,qmlName: "MyReceiversTestObject");
94
95 qmlRegisterUncreatableType<MyUncreateableBaseClass>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyUncreateableBaseClass", reason: "Cannot create MyUncreateableBaseClass");
96 qmlRegisterType<MyCreateableDerivedClass>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyCreateableDerivedClass");
97
98 qmlRegisterUncreatableType<MyUncreateableBaseClass,1>(uri: "Test", versionMajor: 1, versionMinor: 1, qmlName: "MyUncreateableBaseClass", reason: "Cannot create MyUncreateableBaseClass");
99 qmlRegisterType<MyCreateableDerivedClass,1>(uri: "Test", versionMajor: 1, versionMinor: 1, qmlName: "MyCreateableDerivedClass");
100
101 qmlRegisterExtendedUncreatableType<MyExtendedUncreateableBaseClass, MyExtendedUncreateableBaseClassExtension>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyExtendedUncreateableBaseClass", reason: "Cannot create MyExtendedUncreateableBaseClass");
102 qmlRegisterExtendedUncreatableType<MyExtendedUncreateableBaseClass, MyExtendedUncreateableBaseClassExtension, 1>(uri: "Test", versionMajor: 1, versionMinor: 1, qmlName: "MyExtendedUncreateableBaseClass", reason: "Cannot create MyExtendedUncreateableBaseClass");
103 qmlRegisterType<MyExtendedCreateableDerivedClass>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyExtendedCreateableDerivedClass");
104
105 qmlRegisterCustomType<CustomBinding>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "CustomBinding", parser: new CustomBindingParser);
106 qmlRegisterCustomType<SimpleObjectWithCustomParser>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "SimpleObjectWithCustomParser", parser: new SimpleObjectCustomParser);
107
108 qmlRegisterCustomExtendedType<SimpleObjectWithCustomParser, SimpleObjectExtension>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "SimpleExtendedObjectWithCustomParser", parser: new SimpleObjectCustomParser);
109
110 qmlRegisterType<RootObjectInCreationTester>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "RootObjectInCreationTester");
111
112 qmlRegisterType<MyCompositeBaseType>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyCompositeBaseType");
113
114 qmlRegisterSingletonType<MyTypeObjectSingleton>(uri: "Test", versionMajor: 1, versionMinor: 0, typeName: "MyTypeObjectSingleton", callback: myTypeObjectSingleton);
115 qmlRegisterSingletonType(uri: "Test", versionMajor: 1, versionMinor: 0, typeName: "MyQJSValueQObjectSingleton", callback: myQJSValueQObjectSingleton);
116
117 qmlRegisterType<MyArrayBufferTestClass>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "MyArrayBufferTestClass");
118
119 qmlRegisterType<LazyDeferredSubObject>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "LazyDeferredSubObject");
120 qmlRegisterType<DeferredProperties>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "DeferredProperties");
121
122 qmlRegisterTypesAndRevisions<Extended, Foreign, ForeignExtended>(uri: "Test", versionMajor: 1);
123 qmlRegisterTypesAndRevisions<BareSingleton>(uri: "Test", versionMajor: 1);
124 qmlRegisterTypesAndRevisions<UncreatableSingleton>(uri: "Test", versionMajor: 1);
125}
126
127QVariant myCustomVariantTypeConverter(const QString &data)
128{
129 MyCustomVariantType rv;
130 rv.a = data.toInt();
131 return QVariant::fromValue(value: rv);
132}
133
134
135void CustomBindingParser::applyBindings(QObject *object, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
136{
137 CustomBinding *customBinding = qobject_cast<CustomBinding*>(object);
138 Q_ASSERT(customBinding);
139 customBinding->compilationUnit = compilationUnit;
140 customBinding->bindings = bindings;
141}
142
143void CustomBinding::componentComplete()
144{
145 Q_ASSERT(m_target);
146
147 foreach (const QV4::CompiledData::Binding *binding, bindings) {
148 QString name = compilationUnit->stringAt(index: binding->propertyNameIndex);
149
150 int bindingId = binding->value.compiledScriptIndex;
151
152 QQmlContextData *context = QQmlContextData::get(context: qmlContext(this));
153
154 QQmlProperty property(m_target, name, qmlContext(this));
155 QV4::Scope scope(qmlEngine(this)->handle());
156 QV4::Scoped<QV4::QmlContext> qmlContext(scope, QV4::QmlContext::create(parent: scope.engine->rootContext(), context, scopeObject: m_target));
157 QQmlBinding *qmlBinding = QQmlBinding::create(property: &QQmlPropertyPrivate::get(p: property)->core,
158 function: compilationUnit->runtimeFunctions[bindingId], obj: m_target, ctxt: context, scope: qmlContext);
159 qmlBinding->setTarget(property);
160 QQmlPropertyPrivate::setBinding(that: property, qmlBinding);
161 }
162}
163
164void EnumSupportingCustomParser::verifyBindings(const QQmlRefPointer<QV4::ExecutableCompilationUnit> &compilationUnit, const QList<const QV4::CompiledData::Binding *> &bindings)
165{
166 if (bindings.count() != 1) {
167 error(binding: bindings.first(), QStringLiteral("Custom parser invoked incorrectly for unit test"));
168 return;
169 }
170
171 const QV4::CompiledData::Binding *binding = bindings.first();
172 if (compilationUnit->stringAt(index: binding->propertyNameIndex) != QStringLiteral("foo")) {
173 error(binding, QStringLiteral("Custom parser invoked with the wrong property name"));
174 return;
175 }
176
177 if (binding->type != QV4::CompiledData::Binding::Type_Script) {
178 error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Expected script that evaluates to enum"));
179 return;
180 }
181 QByteArray script = compilationUnit->stringAt(index: binding->stringIndex).toUtf8();
182 bool ok;
183 int v = evaluateEnum(script, ok: &ok);
184 if (!ok) {
185 error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Script did not evaluate to enum"));
186 return;
187 }
188 if (v != MyEnum1Class::A_13) {
189 error(binding, QStringLiteral("Custom parser invoked with the wrong property value. Enum value is not the expected value."));
190 return;
191 }
192}
193
194void SimpleObjectCustomParser::applyBindings(QObject *object, const QQmlRefPointer<QV4::ExecutableCompilationUnit> &, const QList<const QV4::CompiledData::Binding *> &bindings)
195{
196 SimpleObjectWithCustomParser *o = qobject_cast<SimpleObjectWithCustomParser*>(object);
197 Q_ASSERT(o);
198 o->setCustomBindingsCount(bindings.count());
199}
200
201
202MyQmlObject::MyQmlObject()
203 : m_value(-1)
204 , m_interface(nullptr)
205 , m_qmlobject(nullptr)
206 , m_childAddedEventCount(0)
207{
208 qRegisterMetaType<MyCustomVariantType>(typeName: "MyCustomVariantType");
209}
210
211bool MyQmlObject::event(QEvent *event)
212{
213 if (event->type() == QEvent::ChildAdded)
214 m_childAddedEventCount++;
215 return QObject::event(event);
216}
217
218UncreatableSingleton *UncreatableSingleton::instance()
219{
220 static UncreatableSingleton instance;
221 return &instance;
222}
223

source code of qtdeclarative/tests/auto/qml/qqmllanguage/testtypes.cpp