1 | // Copyright (C) 2016 The Qt Company Ltd. |
2 | // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only |
3 | |
4 | #include "qmetaobjectbuilder_p.h" |
5 | |
6 | #include "qobject_p.h" |
7 | #include "qmetaobject_p.h" |
8 | |
9 | #include <vector> |
10 | #include <stdlib.h> |
11 | |
12 | QT_BEGIN_NAMESPACE |
13 | |
14 | /*! |
15 | \class QMetaObjectBuilder |
16 | \inmodule QtCore |
17 | \internal |
18 | \brief The QMetaObjectBuilder class supports building QMetaObject objects at runtime. |
19 | |
20 | */ |
21 | |
22 | /*! |
23 | \enum QMetaObjectBuilder::AddMember |
24 | This enum defines which members of QMetaObject should be copied by QMetaObjectBuilder::addMetaObject() |
25 | |
26 | \value ClassName Add the class name. |
27 | \value SuperClass Add the super class. |
28 | \value Methods Add methods that aren't signals or slots. |
29 | \value Signals Add signals. |
30 | \value Slots Add slots. |
31 | \value Constructors Add constructors. |
32 | \value Properties Add properties. |
33 | \value Enumerators Add enumerators. |
34 | \value ClassInfos Add items of class information. |
35 | \value RelatedMetaObjects Add related meta objects. |
36 | \value StaticMetacall Add the static metacall function. |
37 | \value PublicMethods Add public methods (ignored for signals). |
38 | \value ProtectedMethods Add protected methods (ignored for signals). |
39 | \value PrivateMethods All private methods (ignored for signals). |
40 | \value AllMembers Add all members. |
41 | \value AllPrimaryMembers Add everything except the class name, super class, and static metacall function. |
42 | */ |
43 | |
44 | // copied from moc's generator.cpp |
45 | namespace QtPrivate { |
46 | Q_CORE_EXPORT bool isBuiltinType(const QByteArray &type) |
47 | { |
48 | int id = QMetaType::fromName(name: type).id(); |
49 | if (!id && !type.isEmpty() && type != "void" ) |
50 | return false; |
51 | return (id < QMetaType::User); |
52 | } |
53 | } // namespace QtPrivate |
54 | |
55 | // copied from qmetaobject.cpp |
56 | [[maybe_unused]] static inline const QMetaObjectPrivate *qmobPriv(const uint* data) |
57 | { return reinterpret_cast<const QMetaObjectPrivate*>(data); } |
58 | |
59 | class QMetaMethodBuilderPrivate |
60 | { |
61 | public: |
62 | QMetaMethodBuilderPrivate |
63 | (QMetaMethod::MethodType _methodType, |
64 | const QByteArray& _signature, |
65 | const QByteArray& _returnType = QByteArray("void" ), |
66 | QMetaMethod::Access _access = QMetaMethod::Public, |
67 | int _revision = 0) |
68 | : signature(QMetaObject::normalizedSignature(method: _signature.constData())), |
69 | returnType(QMetaObject::normalizedType(type: _returnType)), |
70 | attributes(((int)_access) | (((int)_methodType) << 2)), |
71 | revision(_revision) |
72 | { |
73 | Q_ASSERT((_methodType == QMetaMethod::Constructor) == returnType.isNull()); |
74 | } |
75 | |
76 | QByteArray signature; |
77 | QByteArray returnType; |
78 | QList<QByteArray> parameterNames; |
79 | QByteArray tag; |
80 | int attributes; |
81 | int revision; |
82 | |
83 | QMetaMethod::MethodType methodType() const |
84 | { |
85 | return (QMetaMethod::MethodType)((attributes & MethodTypeMask) >> 2); |
86 | } |
87 | |
88 | QMetaMethod::Access access() const |
89 | { |
90 | return (QMetaMethod::Access)(attributes & AccessMask); |
91 | } |
92 | |
93 | void setAccess(QMetaMethod::Access value) |
94 | { |
95 | attributes = ((attributes & ~AccessMask) | (int)value); |
96 | } |
97 | |
98 | QList<QByteArray> parameterTypes() const |
99 | { |
100 | return QMetaObjectPrivate::parameterTypeNamesFromSignature(signature); |
101 | } |
102 | |
103 | int parameterCount() const |
104 | { |
105 | return parameterTypes().size(); |
106 | } |
107 | |
108 | QByteArray name() const |
109 | { |
110 | return signature.left(len: qMax(a: signature.indexOf(c: '('), b: 0)); |
111 | } |
112 | }; |
113 | Q_DECLARE_TYPEINFO(QMetaMethodBuilderPrivate, Q_RELOCATABLE_TYPE); |
114 | |
115 | class QMetaPropertyBuilderPrivate |
116 | { |
117 | public: |
118 | QMetaPropertyBuilderPrivate |
119 | (const QByteArray& _name, const QByteArray& _type, QMetaType _metaType, int notifierIdx=-1, |
120 | int _revision = 0) |
121 | : name(_name), |
122 | type(QMetaObject::normalizedType(type: _type.constData())), |
123 | metaType(_metaType), |
124 | flags(Readable | Writable | Scriptable), notifySignal(notifierIdx), |
125 | revision(_revision) |
126 | { |
127 | |
128 | } |
129 | |
130 | QByteArray name; |
131 | QByteArray type; |
132 | QMetaType metaType; |
133 | int flags; |
134 | int notifySignal; |
135 | int revision; |
136 | |
137 | bool flag(int f) const |
138 | { |
139 | return ((flags & f) != 0); |
140 | } |
141 | |
142 | void setFlag(int f, bool value) |
143 | { |
144 | if (value) |
145 | flags |= f; |
146 | else |
147 | flags &= ~f; |
148 | } |
149 | }; |
150 | Q_DECLARE_TYPEINFO(QMetaPropertyBuilderPrivate, Q_RELOCATABLE_TYPE); |
151 | |
152 | class QMetaEnumBuilderPrivate |
153 | { |
154 | public: |
155 | QMetaEnumBuilderPrivate(const QByteArray &_name) |
156 | : name(_name), enumName(_name), isFlag(false), isScoped(false) |
157 | { |
158 | } |
159 | |
160 | QByteArray name; |
161 | QByteArray enumName; |
162 | QMetaType metaType; |
163 | bool isFlag; |
164 | bool isScoped; |
165 | QList<QByteArray> keys; |
166 | QList<int> values; |
167 | }; |
168 | Q_DECLARE_TYPEINFO(QMetaEnumBuilderPrivate, Q_RELOCATABLE_TYPE); |
169 | |
170 | class QMetaObjectBuilderPrivate |
171 | { |
172 | public: |
173 | QMetaObjectBuilderPrivate() |
174 | : flags(0) |
175 | { |
176 | superClass = &QObject::staticMetaObject; |
177 | staticMetacallFunction = nullptr; |
178 | } |
179 | |
180 | bool hasRevisionedMethods() const; |
181 | |
182 | QByteArray className; |
183 | const QMetaObject *superClass; |
184 | QMetaObjectBuilder::StaticMetacallFunction staticMetacallFunction; |
185 | std::vector<QMetaMethodBuilderPrivate> methods; |
186 | std::vector<QMetaMethodBuilderPrivate> constructors; |
187 | std::vector<QMetaPropertyBuilderPrivate> properties; |
188 | QList<QByteArray> classInfoNames; |
189 | QList<QByteArray> classInfoValues; |
190 | std::vector<QMetaEnumBuilderPrivate> enumerators; |
191 | QList<const QMetaObject *> relatedMetaObjects; |
192 | MetaObjectFlags flags; |
193 | }; |
194 | |
195 | bool QMetaObjectBuilderPrivate::hasRevisionedMethods() const |
196 | { |
197 | for (const auto &method : methods) { |
198 | if (method.revision) |
199 | return true; |
200 | } |
201 | return false; |
202 | } |
203 | |
204 | /*! |
205 | Constructs a new QMetaObjectBuilder. |
206 | */ |
207 | QMetaObjectBuilder::QMetaObjectBuilder() |
208 | { |
209 | d = new QMetaObjectBuilderPrivate(); |
210 | } |
211 | |
212 | /*! |
213 | Constructs a new QMetaObjectBuilder which is a copy of the |
214 | meta object information in \a prototype. Note: the super class |
215 | contents for \a prototype are not copied, only the immediate |
216 | class that is defined by \a prototype. |
217 | |
218 | The \a members parameter indicates which members of \a prototype |
219 | should be added. The default is AllMembers. |
220 | |
221 | \sa addMetaObject() |
222 | */ |
223 | QMetaObjectBuilder::QMetaObjectBuilder(const QMetaObject *prototype, |
224 | QMetaObjectBuilder::AddMembers members) |
225 | { |
226 | d = new QMetaObjectBuilderPrivate(); |
227 | addMetaObject(prototype, members); |
228 | } |
229 | |
230 | /*! |
231 | Destroys this meta object builder. |
232 | */ |
233 | QMetaObjectBuilder::~QMetaObjectBuilder() |
234 | { |
235 | delete d; |
236 | } |
237 | |
238 | /*! |
239 | Returns the name of the class being constructed by this |
240 | meta object builder. The default value is an empty QByteArray. |
241 | |
242 | \sa setClassName(), superClass() |
243 | */ |
244 | QByteArray QMetaObjectBuilder::className() const |
245 | { |
246 | return d->className; |
247 | } |
248 | |
249 | /*! |
250 | Sets the \a name of the class being constructed by this |
251 | meta object builder. |
252 | |
253 | \sa className(), setSuperClass() |
254 | */ |
255 | void QMetaObjectBuilder::setClassName(const QByteArray &name) |
256 | { |
257 | d->className = name; |
258 | } |
259 | |
260 | /*! |
261 | Returns the superclass meta object of the class being constructed |
262 | by this meta object builder. The default value is the meta object |
263 | for QObject. |
264 | |
265 | \sa setSuperClass(), className() |
266 | */ |
267 | const QMetaObject *QMetaObjectBuilder::superClass() const |
268 | { |
269 | return d->superClass; |
270 | } |
271 | |
272 | /*! |
273 | Sets the superclass meta object of the class being constructed |
274 | by this meta object builder to \a meta. The \a meta parameter |
275 | must not be null. |
276 | |
277 | \sa superClass(), setClassName() |
278 | */ |
279 | void QMetaObjectBuilder::setSuperClass(const QMetaObject *meta) |
280 | { |
281 | Q_ASSERT(meta); |
282 | d->superClass = meta; |
283 | } |
284 | |
285 | /*! |
286 | Returns the flags of the class being constructed by this meta object |
287 | builder. |
288 | |
289 | \sa setFlags() |
290 | */ |
291 | MetaObjectFlags QMetaObjectBuilder::flags() const |
292 | { |
293 | return d->flags; |
294 | } |
295 | |
296 | /*! |
297 | Sets the \a flags of the class being constructed by this meta object |
298 | builder. |
299 | |
300 | \sa flags() |
301 | */ |
302 | void QMetaObjectBuilder::setFlags(MetaObjectFlags flags) |
303 | { |
304 | d->flags = flags; |
305 | } |
306 | |
307 | /*! |
308 | Returns the number of methods in this class, excluding the number |
309 | of methods in the base class. These include signals and slots |
310 | as well as normal member functions. |
311 | |
312 | \sa addMethod(), method(), removeMethod(), indexOfMethod() |
313 | */ |
314 | int QMetaObjectBuilder::methodCount() const |
315 | { |
316 | return int(d->methods.size()); |
317 | } |
318 | |
319 | /*! |
320 | Returns the number of constructors in this class. |
321 | |
322 | \sa addConstructor(), constructor(), removeConstructor(), indexOfConstructor() |
323 | */ |
324 | int QMetaObjectBuilder::constructorCount() const |
325 | { |
326 | return int(d->constructors.size()); |
327 | } |
328 | |
329 | /*! |
330 | Returns the number of properties in this class, excluding the number |
331 | of properties in the base class. |
332 | |
333 | \sa addProperty(), property(), removeProperty(), indexOfProperty() |
334 | */ |
335 | int QMetaObjectBuilder::propertyCount() const |
336 | { |
337 | return int(d->properties.size()); |
338 | } |
339 | |
340 | /*! |
341 | Returns the number of enumerators in this class, excluding the |
342 | number of enumerators in the base class. |
343 | |
344 | \sa addEnumerator(), enumerator(), removeEnumerator() |
345 | \sa indexOfEnumerator() |
346 | */ |
347 | int QMetaObjectBuilder::enumeratorCount() const |
348 | { |
349 | return int(d->enumerators.size()); |
350 | } |
351 | |
352 | /*! |
353 | Returns the number of items of class information in this class, |
354 | exclusing the number of items of class information in the base class. |
355 | |
356 | \sa addClassInfo(), classInfoName(), classInfoValue(), removeClassInfo() |
357 | \sa indexOfClassInfo() |
358 | */ |
359 | int QMetaObjectBuilder::classInfoCount() const |
360 | { |
361 | return d->classInfoNames.size(); |
362 | } |
363 | |
364 | /*! |
365 | Returns the number of related meta objects that are associated |
366 | with this class. |
367 | |
368 | Related meta objects are used when resolving the enumerated type |
369 | associated with a property, where the enumerated type is in a |
370 | different class from the property. |
371 | |
372 | \sa addRelatedMetaObject(), relatedMetaObject() |
373 | \sa removeRelatedMetaObject() |
374 | */ |
375 | int QMetaObjectBuilder::relatedMetaObjectCount() const |
376 | { |
377 | return d->relatedMetaObjects.size(); |
378 | } |
379 | |
380 | /*! |
381 | Adds a new public method to this class with the specified \a signature. |
382 | Returns an object that can be used to adjust the other attributes |
383 | of the method. The \a signature will be normalized before it is |
384 | added to the class. |
385 | |
386 | \sa method(), methodCount(), removeMethod(), indexOfMethod() |
387 | */ |
388 | QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray &signature) |
389 | { |
390 | int index = int(d->methods.size()); |
391 | d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Method, signature)); |
392 | return QMetaMethodBuilder(this, index); |
393 | } |
394 | |
395 | /*! |
396 | Adds a new public method to this class with the specified |
397 | \a signature and \a returnType. Returns an object that can be |
398 | used to adjust the other attributes of the method. The \a signature |
399 | and \a returnType will be normalized before they are added to |
400 | the class. |
401 | |
402 | \sa method(), methodCount(), removeMethod(), indexOfMethod() |
403 | */ |
404 | QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QByteArray &signature, |
405 | const QByteArray &returnType) |
406 | { |
407 | int index = int(d->methods.size()); |
408 | d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Method, signature, returnType)); |
409 | return QMetaMethodBuilder(this, index); |
410 | } |
411 | |
412 | /*! |
413 | Adds a new public method to this class that has the same information as |
414 | \a prototype. This is used to clone the methods of an existing |
415 | QMetaObject. Returns an object that can be used to adjust the |
416 | attributes of the method. |
417 | |
418 | This function will detect if \a prototype is an ordinary method, |
419 | signal, slot, or constructor and act accordingly. |
420 | |
421 | \sa method(), methodCount(), removeMethod(), indexOfMethod() |
422 | */ |
423 | QMetaMethodBuilder QMetaObjectBuilder::addMethod(const QMetaMethod &prototype) |
424 | { |
425 | QMetaMethodBuilder method; |
426 | if (prototype.methodType() == QMetaMethod::Method) |
427 | method = addMethod(signature: prototype.methodSignature()); |
428 | else if (prototype.methodType() == QMetaMethod::Signal) |
429 | method = addSignal(signature: prototype.methodSignature()); |
430 | else if (prototype.methodType() == QMetaMethod::Slot) |
431 | method = addSlot(signature: prototype.methodSignature()); |
432 | else if (prototype.methodType() == QMetaMethod::Constructor) |
433 | method = addConstructor(signature: prototype.methodSignature()); |
434 | method.setReturnType(prototype.typeName()); |
435 | method.setParameterNames(prototype.parameterNames()); |
436 | method.setTag(prototype.tag()); |
437 | method.setAccess(prototype.access()); |
438 | method.setAttributes(prototype.attributes()); |
439 | method.setRevision(prototype.revision()); |
440 | return method; |
441 | } |
442 | |
443 | /*! |
444 | Adds a new public slot to this class with the specified \a signature. |
445 | Returns an object that can be used to adjust the other attributes |
446 | of the slot. The \a signature will be normalized before it is |
447 | added to the class. |
448 | |
449 | \sa addMethod(), addSignal(), indexOfSlot() |
450 | */ |
451 | QMetaMethodBuilder QMetaObjectBuilder::addSlot(const QByteArray &signature) |
452 | { |
453 | int index = int(d->methods.size()); |
454 | d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Slot, signature)); |
455 | return QMetaMethodBuilder(this, index); |
456 | } |
457 | |
458 | /*! |
459 | Adds a new signal to this class with the specified \a signature. |
460 | Returns an object that can be used to adjust the other attributes |
461 | of the signal. The \a signature will be normalized before it is |
462 | added to the class. |
463 | |
464 | \sa addMethod(), addSlot(), indexOfSignal() |
465 | */ |
466 | QMetaMethodBuilder QMetaObjectBuilder::addSignal(const QByteArray &signature) |
467 | { |
468 | int index = int(d->methods.size()); |
469 | d->methods.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Signal, signature, |
470 | QByteArray("void" ), QMetaMethod::Public)); |
471 | return QMetaMethodBuilder(this, index); |
472 | } |
473 | |
474 | /*! |
475 | Adds a new constructor to this class with the specified \a signature. |
476 | Returns an object that can be used to adjust the other attributes |
477 | of the constructor. The \a signature will be normalized before it is |
478 | added to the class. |
479 | |
480 | \sa constructor(), constructorCount(), removeConstructor() |
481 | \sa indexOfConstructor() |
482 | */ |
483 | QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QByteArray &signature) |
484 | { |
485 | int index = int(d->constructors.size()); |
486 | d->constructors.push_back(x: QMetaMethodBuilderPrivate(QMetaMethod::Constructor, signature, |
487 | /*returnType=*/QByteArray())); |
488 | return QMetaMethodBuilder(this, -(index + 1)); |
489 | } |
490 | |
491 | /*! |
492 | Adds a new constructor to this class that has the same information as |
493 | \a prototype. This is used to clone the constructors of an existing |
494 | QMetaObject. Returns an object that can be used to adjust the |
495 | attributes of the constructor. |
496 | |
497 | This function requires that \a prototype be a constructor. |
498 | |
499 | \sa constructor(), constructorCount(), removeConstructor() |
500 | \sa indexOfConstructor() |
501 | */ |
502 | QMetaMethodBuilder QMetaObjectBuilder::addConstructor(const QMetaMethod &prototype) |
503 | { |
504 | Q_ASSERT(prototype.methodType() == QMetaMethod::Constructor); |
505 | QMetaMethodBuilder ctor = addConstructor(signature: prototype.methodSignature()); |
506 | ctor.setReturnType(prototype.typeName()); |
507 | ctor.setParameterNames(prototype.parameterNames()); |
508 | ctor.setTag(prototype.tag()); |
509 | ctor.setAccess(prototype.access()); |
510 | ctor.setAttributes(prototype.attributes()); |
511 | return ctor; |
512 | } |
513 | |
514 | /*! |
515 | Adds a new readable/writable property to this class with the |
516 | specified \a name and \a type. Returns an object that can be used |
517 | to adjust the other attributes of the property. The \a type will |
518 | be normalized before it is added to the class. \a notifierId will |
519 | be registered as the property's \e notify signal. |
520 | |
521 | \sa property(), propertyCount(), removeProperty(), indexOfProperty() |
522 | */ |
523 | QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type, |
524 | int notifierId) |
525 | { |
526 | return addProperty(name, type, metaType: QMetaType::fromName(name: type), notifierId); |
527 | } |
528 | |
529 | /*! |
530 | \overload |
531 | */ |
532 | QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QByteArray &name, const QByteArray &type, QMetaType metaType, int notifierId) |
533 | { |
534 | int index = int(d->properties.size()); |
535 | d->properties.push_back(x: QMetaPropertyBuilderPrivate(name, type, metaType, notifierId)); |
536 | return QMetaPropertyBuilder(this, index); |
537 | } |
538 | |
539 | /*! |
540 | Adds a new property to this class that has the same information as |
541 | \a prototype. This is used to clone the properties of an existing |
542 | QMetaObject. Returns an object that can be used to adjust the |
543 | attributes of the property. |
544 | |
545 | \sa property(), propertyCount(), removeProperty(), indexOfProperty() |
546 | */ |
547 | QMetaPropertyBuilder QMetaObjectBuilder::addProperty(const QMetaProperty &prototype) |
548 | { |
549 | QMetaPropertyBuilder property = addProperty(name: prototype.name(), type: prototype.typeName(), metaType: prototype.metaType()); |
550 | property.setReadable(prototype.isReadable()); |
551 | property.setWritable(prototype.isWritable()); |
552 | property.setResettable(prototype.isResettable()); |
553 | property.setDesignable(prototype.isDesignable()); |
554 | property.setScriptable(prototype.isScriptable()); |
555 | property.setStored(prototype.isStored()); |
556 | property.setUser(prototype.isUser()); |
557 | property.setStdCppSet(prototype.hasStdCppSet()); |
558 | property.setEnumOrFlag(prototype.isEnumType()); |
559 | property.setConstant(prototype.isConstant()); |
560 | property.setFinal(prototype.isFinal()); |
561 | property.setRevision(prototype.revision()); |
562 | if (prototype.hasNotifySignal()) { |
563 | // Find an existing method for the notify signal, or add a new one. |
564 | QMetaMethod method = prototype.notifySignal(); |
565 | int index = indexOfMethod(signature: method.methodSignature()); |
566 | if (index == -1) |
567 | index = addMethod(prototype: method).index(); |
568 | d->properties[property._index].notifySignal = index; |
569 | } |
570 | return property; |
571 | } |
572 | |
573 | /*! |
574 | Adds a new enumerator to this class with the specified |
575 | \a name. Returns an object that can be used to adjust |
576 | the other attributes of the enumerator. |
577 | |
578 | \sa enumerator(), enumeratorCount(), removeEnumerator() |
579 | \sa indexOfEnumerator() |
580 | */ |
581 | QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QByteArray &name) |
582 | { |
583 | int index = int(d->enumerators.size()); |
584 | d->enumerators.push_back(x: QMetaEnumBuilderPrivate(name)); |
585 | return QMetaEnumBuilder(this, index); |
586 | } |
587 | |
588 | /*! |
589 | Adds a new enumerator to this class that has the same information as |
590 | \a prototype. This is used to clone the enumerators of an existing |
591 | QMetaObject. Returns an object that can be used to adjust the |
592 | attributes of the enumerator. |
593 | |
594 | \sa enumerator(), enumeratorCount(), removeEnumerator() |
595 | \sa indexOfEnumerator() |
596 | */ |
597 | QMetaEnumBuilder QMetaObjectBuilder::addEnumerator(const QMetaEnum &prototype) |
598 | { |
599 | QMetaEnumBuilder en = addEnumerator(name: prototype.name()); |
600 | en.setEnumName(prototype.enumName()); |
601 | en.setMetaType(prototype.metaType()); |
602 | en.setIsFlag(prototype.isFlag()); |
603 | en.setIsScoped(prototype.isScoped()); |
604 | int count = prototype.keyCount(); |
605 | for (int index = 0; index < count; ++index) |
606 | en.addKey(name: prototype.key(index), value: prototype.value(index)); |
607 | return en; |
608 | } |
609 | |
610 | /*! |
611 | Adds \a name and \a value as an item of class information to this class. |
612 | Returns the index of the new item of class information. |
613 | |
614 | \sa classInfoCount(), classInfoName(), classInfoValue(), removeClassInfo() |
615 | \sa indexOfClassInfo() |
616 | */ |
617 | int QMetaObjectBuilder::addClassInfo(const QByteArray &name, const QByteArray &value) |
618 | { |
619 | int index = d->classInfoNames.size(); |
620 | d->classInfoNames += name; |
621 | d->classInfoValues += value; |
622 | return index; |
623 | } |
624 | |
625 | /*! |
626 | Adds \a meta to this class as a related meta object. Returns |
627 | the index of the new related meta object entry. |
628 | |
629 | Related meta objects are used when resolving the enumerated type |
630 | associated with a property, where the enumerated type is in a |
631 | different class from the property. |
632 | |
633 | \sa relatedMetaObjectCount(), relatedMetaObject() |
634 | \sa removeRelatedMetaObject() |
635 | */ |
636 | int QMetaObjectBuilder::addRelatedMetaObject(const QMetaObject *meta) |
637 | { |
638 | Q_ASSERT(meta); |
639 | int index = d->relatedMetaObjects.size(); |
640 | d->relatedMetaObjects.append(t: meta); |
641 | return index; |
642 | } |
643 | |
644 | /*! |
645 | Adds the contents of \a prototype to this meta object builder. |
646 | This function is useful for cloning the contents of an existing QMetaObject. |
647 | |
648 | The \a members parameter indicates which members of \a prototype |
649 | should be added. The default is AllMembers. |
650 | */ |
651 | void QMetaObjectBuilder::addMetaObject(const QMetaObject *prototype, |
652 | QMetaObjectBuilder::AddMembers members) |
653 | { |
654 | Q_ASSERT(prototype); |
655 | int index; |
656 | |
657 | if ((members & ClassName) != 0) |
658 | d->className = prototype->className(); |
659 | |
660 | if ((members & SuperClass) != 0) |
661 | d->superClass = prototype->superClass(); |
662 | |
663 | if ((members & (Methods | Signals | Slots)) != 0) { |
664 | for (index = prototype->methodOffset(); index < prototype->methodCount(); ++index) { |
665 | QMetaMethod method = prototype->method(index); |
666 | if (method.methodType() != QMetaMethod::Signal) { |
667 | if (method.access() == QMetaMethod::Public && (members & PublicMethods) == 0) |
668 | continue; |
669 | if (method.access() == QMetaMethod::Private && (members & PrivateMethods) == 0) |
670 | continue; |
671 | if (method.access() == QMetaMethod::Protected && (members & ProtectedMethods) == 0) |
672 | continue; |
673 | } |
674 | if (method.methodType() == QMetaMethod::Method && (members & Methods) != 0) { |
675 | addMethod(prototype: method); |
676 | } else if (method.methodType() == QMetaMethod::Signal && |
677 | (members & Signals) != 0) { |
678 | addMethod(prototype: method); |
679 | } else if (method.methodType() == QMetaMethod::Slot && |
680 | (members & Slots) != 0) { |
681 | addMethod(prototype: method); |
682 | } |
683 | } |
684 | } |
685 | |
686 | if ((members & Constructors) != 0) { |
687 | for (index = 0; index < prototype->constructorCount(); ++index) |
688 | addConstructor(prototype: prototype->constructor(index)); |
689 | } |
690 | |
691 | if ((members & Properties) != 0) { |
692 | for (index = prototype->propertyOffset(); index < prototype->propertyCount(); ++index) |
693 | addProperty(prototype: prototype->property(index)); |
694 | } |
695 | |
696 | if ((members & Enumerators) != 0) { |
697 | for (index = prototype->enumeratorOffset(); index < prototype->enumeratorCount(); ++index) |
698 | addEnumerator(prototype: prototype->enumerator(index)); |
699 | } |
700 | |
701 | if ((members & ClassInfos) != 0) { |
702 | for (index = prototype->classInfoOffset(); index < prototype->classInfoCount(); ++index) { |
703 | QMetaClassInfo ci = prototype->classInfo(index); |
704 | addClassInfo(name: ci.name(), value: ci.value()); |
705 | } |
706 | } |
707 | |
708 | if ((members & RelatedMetaObjects) != 0) { |
709 | Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 2); |
710 | const auto *objects = prototype->d.relatedMetaObjects; |
711 | if (objects) { |
712 | while (*objects != nullptr) { |
713 | addRelatedMetaObject(meta: *objects); |
714 | ++objects; |
715 | } |
716 | } |
717 | } |
718 | |
719 | if ((members & StaticMetacall) != 0) { |
720 | Q_ASSERT(qmobPriv(prototype->d.data)->revision >= 6); |
721 | if (prototype->d.static_metacall) |
722 | setStaticMetacallFunction(prototype->d.static_metacall); |
723 | } |
724 | } |
725 | |
726 | /*! |
727 | Returns the method at \a index in this class. |
728 | |
729 | \sa methodCount(), addMethod(), removeMethod(), indexOfMethod() |
730 | */ |
731 | QMetaMethodBuilder QMetaObjectBuilder::method(int index) const |
732 | { |
733 | if (uint(index) < d->methods.size()) |
734 | return QMetaMethodBuilder(this, index); |
735 | else |
736 | return QMetaMethodBuilder(); |
737 | } |
738 | |
739 | /*! |
740 | Returns the constructor at \a index in this class. |
741 | |
742 | \sa methodCount(), addMethod(), removeMethod(), indexOfConstructor() |
743 | */ |
744 | QMetaMethodBuilder QMetaObjectBuilder::constructor(int index) const |
745 | { |
746 | if (uint(index) < d->constructors.size()) |
747 | return QMetaMethodBuilder(this, -(index + 1)); |
748 | else |
749 | return QMetaMethodBuilder(); |
750 | } |
751 | |
752 | /*! |
753 | Returns the property at \a index in this class. |
754 | |
755 | \sa methodCount(), addMethod(), removeMethod(), indexOfProperty() |
756 | */ |
757 | QMetaPropertyBuilder QMetaObjectBuilder::property(int index) const |
758 | { |
759 | if (uint(index) < d->properties.size()) |
760 | return QMetaPropertyBuilder(this, index); |
761 | else |
762 | return QMetaPropertyBuilder(); |
763 | } |
764 | |
765 | /*! |
766 | Returns the enumerator at \a index in this class. |
767 | |
768 | \sa enumeratorCount(), addEnumerator(), removeEnumerator() |
769 | \sa indexOfEnumerator() |
770 | */ |
771 | QMetaEnumBuilder QMetaObjectBuilder::enumerator(int index) const |
772 | { |
773 | if (uint(index) < d->enumerators.size()) |
774 | return QMetaEnumBuilder(this, index); |
775 | else |
776 | return QMetaEnumBuilder(); |
777 | } |
778 | |
779 | /*! |
780 | Returns the related meta object at \a index in this class. |
781 | |
782 | Related meta objects are used when resolving the enumerated type |
783 | associated with a property, where the enumerated type is in a |
784 | different class from the property. |
785 | |
786 | \sa relatedMetaObjectCount(), addRelatedMetaObject() |
787 | \sa removeRelatedMetaObject() |
788 | */ |
789 | const QMetaObject *QMetaObjectBuilder::relatedMetaObject(int index) const |
790 | { |
791 | if (index >= 0 && index < d->relatedMetaObjects.size()) |
792 | return d->relatedMetaObjects[index]; |
793 | else |
794 | return nullptr; |
795 | } |
796 | |
797 | /*! |
798 | Returns the name of the item of class information at \a index |
799 | in this class. |
800 | |
801 | \sa classInfoCount(), addClassInfo(), classInfoValue(), removeClassInfo() |
802 | \sa indexOfClassInfo() |
803 | */ |
804 | QByteArray QMetaObjectBuilder::classInfoName(int index) const |
805 | { |
806 | if (index >= 0 && index < d->classInfoNames.size()) |
807 | return d->classInfoNames[index]; |
808 | else |
809 | return QByteArray(); |
810 | } |
811 | |
812 | /*! |
813 | Returns the value of the item of class information at \a index |
814 | in this class. |
815 | |
816 | \sa classInfoCount(), addClassInfo(), classInfoName(), removeClassInfo() |
817 | \sa indexOfClassInfo() |
818 | */ |
819 | QByteArray QMetaObjectBuilder::classInfoValue(int index) const |
820 | { |
821 | if (index >= 0 && index < d->classInfoValues.size()) |
822 | return d->classInfoValues[index]; |
823 | else |
824 | return QByteArray(); |
825 | } |
826 | |
827 | /*! |
828 | Removes the method at \a index from this class. The indices of |
829 | all following methods will be adjusted downwards by 1. If the |
830 | method is registered as a notify signal on a property, then the |
831 | notify signal will be removed from the property. |
832 | |
833 | \sa methodCount(), addMethod(), method(), indexOfMethod() |
834 | */ |
835 | void QMetaObjectBuilder::removeMethod(int index) |
836 | { |
837 | if (uint(index) < d->methods.size()) { |
838 | d->methods.erase(position: d->methods.begin() + index); |
839 | for (auto &property : d->properties) { |
840 | // Adjust the indices of property notify signal references. |
841 | if (property.notifySignal == index) { |
842 | property.notifySignal = -1; |
843 | } else if (property.notifySignal > index) |
844 | property.notifySignal--; |
845 | } |
846 | } |
847 | } |
848 | |
849 | /*! |
850 | Removes the constructor at \a index from this class. The indices of |
851 | all following constructors will be adjusted downwards by 1. |
852 | |
853 | \sa constructorCount(), addConstructor(), constructor() |
854 | \sa indexOfConstructor() |
855 | */ |
856 | void QMetaObjectBuilder::removeConstructor(int index) |
857 | { |
858 | if (uint(index) < d->constructors.size()) |
859 | d->constructors.erase(position: d->constructors.begin() + index); |
860 | } |
861 | |
862 | /*! |
863 | Removes the property at \a index from this class. The indices of |
864 | all following properties will be adjusted downwards by 1. |
865 | |
866 | \sa propertyCount(), addProperty(), property(), indexOfProperty() |
867 | */ |
868 | void QMetaObjectBuilder::removeProperty(int index) |
869 | { |
870 | if (uint(index) < d->properties.size()) |
871 | d->properties.erase(position: d->properties.begin() + index); |
872 | } |
873 | |
874 | /*! |
875 | Removes the enumerator at \a index from this class. The indices of |
876 | all following enumerators will be adjusted downwards by 1. |
877 | |
878 | \sa enumertorCount(), addEnumerator(), enumerator() |
879 | \sa indexOfEnumerator() |
880 | */ |
881 | void QMetaObjectBuilder::removeEnumerator(int index) |
882 | { |
883 | if (uint(index) < d->enumerators.size()) |
884 | d->enumerators.erase(position: d->enumerators.begin() + index); |
885 | } |
886 | |
887 | /*! |
888 | Removes the item of class information at \a index from this class. |
889 | The indices of all following items will be adjusted downwards by 1. |
890 | |
891 | \sa classInfoCount(), addClassInfo(), classInfoName(), classInfoValue() |
892 | \sa indexOfClassInfo() |
893 | */ |
894 | void QMetaObjectBuilder::removeClassInfo(int index) |
895 | { |
896 | if (index >= 0 && index < d->classInfoNames.size()) { |
897 | d->classInfoNames.removeAt(i: index); |
898 | d->classInfoValues.removeAt(i: index); |
899 | } |
900 | } |
901 | |
902 | /*! |
903 | Removes the related meta object at \a index from this class. |
904 | The indices of all following related meta objects will be adjusted |
905 | downwards by 1. |
906 | |
907 | Related meta objects are used when resolving the enumerated type |
908 | associated with a property, where the enumerated type is in a |
909 | different class from the property. |
910 | |
911 | \sa relatedMetaObjectCount(), addRelatedMetaObject() |
912 | \sa relatedMetaObject() |
913 | */ |
914 | void QMetaObjectBuilder::removeRelatedMetaObject(int index) |
915 | { |
916 | if (index >= 0 && index < d->relatedMetaObjects.size()) |
917 | d->relatedMetaObjects.removeAt(i: index); |
918 | } |
919 | |
920 | /*! |
921 | Finds a method with the specified \a signature and returns its index; |
922 | otherwise returns -1. The \a signature will be normalized by this method. |
923 | |
924 | \sa method(), methodCount(), addMethod(), removeMethod() |
925 | */ |
926 | int QMetaObjectBuilder::indexOfMethod(const QByteArray &signature) |
927 | { |
928 | QByteArray sig = QMetaObject::normalizedSignature(method: signature); |
929 | for (const auto &method : d->methods) { |
930 | if (sig == method.signature) |
931 | return int(&method - &d->methods.front()); |
932 | } |
933 | return -1; |
934 | } |
935 | |
936 | /*! |
937 | Finds a signal with the specified \a signature and returns its index; |
938 | otherwise returns -1. The \a signature will be normalized by this method. |
939 | |
940 | \sa indexOfMethod(), indexOfSlot() |
941 | */ |
942 | int QMetaObjectBuilder::indexOfSignal(const QByteArray &signature) |
943 | { |
944 | QByteArray sig = QMetaObject::normalizedSignature(method: signature); |
945 | for (const auto &method : d->methods) { |
946 | if (method.methodType() == QMetaMethod::Signal && sig == method.signature) |
947 | return int(&method - &d->methods.front()); |
948 | } |
949 | return -1; |
950 | } |
951 | |
952 | /*! |
953 | Finds a slot with the specified \a signature and returns its index; |
954 | otherwise returns -1. The \a signature will be normalized by this method. |
955 | |
956 | \sa indexOfMethod(), indexOfSignal() |
957 | */ |
958 | int QMetaObjectBuilder::indexOfSlot(const QByteArray &signature) |
959 | { |
960 | QByteArray sig = QMetaObject::normalizedSignature(method: signature); |
961 | for (const auto &method : d->methods) { |
962 | if (method.methodType() == QMetaMethod::Slot && sig == method.signature) |
963 | return int(&method - &d->methods.front()); |
964 | } |
965 | return -1; |
966 | } |
967 | |
968 | /*! |
969 | Finds a constructor with the specified \a signature and returns its index; |
970 | otherwise returns -1. The \a signature will be normalized by this method. |
971 | |
972 | \sa constructor(), constructorCount(), addConstructor(), removeConstructor() |
973 | */ |
974 | int QMetaObjectBuilder::indexOfConstructor(const QByteArray &signature) |
975 | { |
976 | QByteArray sig = QMetaObject::normalizedSignature(method: signature); |
977 | for (const auto &constructor : d->constructors) { |
978 | if (sig == constructor.signature) |
979 | return int(&constructor - &d->constructors.front()); |
980 | } |
981 | return -1; |
982 | } |
983 | |
984 | /*! |
985 | Finds a property with the specified \a name and returns its index; |
986 | otherwise returns -1. |
987 | |
988 | \sa property(), propertyCount(), addProperty(), removeProperty() |
989 | */ |
990 | int QMetaObjectBuilder::indexOfProperty(const QByteArray &name) |
991 | { |
992 | for (const auto &property : d->properties) { |
993 | if (name == property.name) |
994 | return int(&property - &d->properties.front()); |
995 | } |
996 | return -1; |
997 | } |
998 | |
999 | /*! |
1000 | Finds an enumerator with the specified \a name and returns its index; |
1001 | otherwise returns -1. |
1002 | |
1003 | \sa enumertor(), enumeratorCount(), addEnumerator(), removeEnumerator() |
1004 | */ |
1005 | int QMetaObjectBuilder::indexOfEnumerator(const QByteArray &name) |
1006 | { |
1007 | for (const auto &enumerator : d->enumerators) { |
1008 | if (name == enumerator.name) |
1009 | return int(&enumerator - &d->enumerators.front()); |
1010 | } |
1011 | return -1; |
1012 | } |
1013 | |
1014 | /*! |
1015 | Finds an item of class information with the specified \a name and |
1016 | returns its index; otherwise returns -1. |
1017 | |
1018 | \sa classInfoName(), classInfoValue(), classInfoCount(), addClassInfo() |
1019 | \sa removeClassInfo() |
1020 | */ |
1021 | int QMetaObjectBuilder::indexOfClassInfo(const QByteArray &name) |
1022 | { |
1023 | for (int index = 0; index < d->classInfoNames.size(); ++index) { |
1024 | if (name == d->classInfoNames[index]) |
1025 | return index; |
1026 | } |
1027 | return -1; |
1028 | } |
1029 | |
1030 | // Align on a specific type boundary. |
1031 | #ifdef ALIGN |
1032 | # undef ALIGN |
1033 | #endif |
1034 | #define ALIGN(size,type) \ |
1035 | (size) = ((size) + sizeof(type) - 1) & ~(sizeof(type) - 1) |
1036 | |
1037 | /*! |
1038 | \class QMetaStringTable |
1039 | \inmodule QtCore |
1040 | \internal |
1041 | \brief The QMetaStringTable class can generate a meta-object string table at runtime. |
1042 | */ |
1043 | |
1044 | QMetaStringTable::QMetaStringTable(const QByteArray &className) |
1045 | : m_index(0) |
1046 | , m_className(className) |
1047 | { |
1048 | const int index = enter(value: m_className); |
1049 | Q_ASSERT(index == 0); |
1050 | Q_UNUSED(index); |
1051 | } |
1052 | |
1053 | // Enters the given value into the string table (if it hasn't already been |
1054 | // entered). Returns the index of the string. |
1055 | int QMetaStringTable::enter(const QByteArray &value) |
1056 | { |
1057 | Entries::iterator it = m_entries.find(key: value); |
1058 | if (it != m_entries.end()) |
1059 | return it.value(); |
1060 | int pos = m_index; |
1061 | m_entries.insert(key: value, value: pos); |
1062 | ++m_index; |
1063 | return pos; |
1064 | } |
1065 | |
1066 | int QMetaStringTable::preferredAlignment() |
1067 | { |
1068 | return alignof(uint); |
1069 | } |
1070 | |
1071 | // Returns the size (in bytes) required for serializing this string table. |
1072 | int QMetaStringTable::blobSize() const |
1073 | { |
1074 | int size = int(m_entries.size() * 2 * sizeof(uint)); |
1075 | Entries::const_iterator it; |
1076 | for (it = m_entries.constBegin(); it != m_entries.constEnd(); ++it) |
1077 | size += it.key().size() + 1; |
1078 | return size; |
1079 | } |
1080 | |
1081 | static void writeString(char *out, int i, const QByteArray &str, |
1082 | const int offsetOfStringdataMember, int &stringdataOffset) |
1083 | { |
1084 | int size = str.size(); |
1085 | int offset = offsetOfStringdataMember + stringdataOffset; |
1086 | uint offsetLen[2] = { uint(offset), uint(size) }; |
1087 | |
1088 | memcpy(dest: out + 2 * i * sizeof(uint), src: &offsetLen, n: 2 * sizeof(uint)); |
1089 | |
1090 | memcpy(dest: out + offset, src: str.constData(), n: size); |
1091 | out[offset + size] = '\0'; |
1092 | |
1093 | stringdataOffset += size + 1; |
1094 | } |
1095 | |
1096 | // Writes strings to string data struct. |
1097 | // The struct consists of an array of QByteArrayData, followed by a char array |
1098 | // containing the actual strings. This format must match the one produced by |
1099 | // moc (see generator.cpp). |
1100 | void QMetaStringTable::writeBlob(char *out) const |
1101 | { |
1102 | Q_ASSERT(!(reinterpret_cast<quintptr>(out) & (preferredAlignment() - 1))); |
1103 | |
1104 | int offsetOfStringdataMember = int(m_entries.size() * 2 * sizeof(uint)); |
1105 | int stringdataOffset = 0; |
1106 | |
1107 | // qt_metacast expects the first string in the string table to be the class name. |
1108 | writeString(out, /*index*/ i: 0, str: m_className, offsetOfStringdataMember, stringdataOffset); |
1109 | |
1110 | for (Entries::ConstIterator it = m_entries.constBegin(), end = m_entries.constEnd(); |
1111 | it != end; ++it) { |
1112 | const int i = it.value(); |
1113 | if (i == 0) |
1114 | continue; |
1115 | const QByteArray &str = it.key(); |
1116 | |
1117 | writeString(out, i, str, offsetOfStringdataMember, stringdataOffset); |
1118 | } |
1119 | } |
1120 | |
1121 | // Returns the sum of all parameters (including return type) for the given |
1122 | // \a methods. This is needed for calculating the size of the methods' |
1123 | // parameter type/name meta-data. |
1124 | static int aggregateParameterCount(const std::vector<QMetaMethodBuilderPrivate> &methods) |
1125 | { |
1126 | int sum = 0; |
1127 | for (const auto &method : methods) |
1128 | sum += method.parameterCount() + 1; // +1 for return type |
1129 | return sum; |
1130 | } |
1131 | |
1132 | enum Mode { |
1133 | Prepare, // compute the size of the metaobject |
1134 | Construct // construct metaobject in pre-allocated buffer |
1135 | }; |
1136 | // Build a QMetaObject in "buf" based on the information in "d". |
1137 | // If the mode is prepare, then return the number of bytes needed to |
1138 | // build the QMetaObject. |
1139 | template<Mode mode> |
1140 | static int buildMetaObject(QMetaObjectBuilderPrivate *d, char *buf, |
1141 | int expectedSize) |
1142 | { |
1143 | Q_UNUSED(expectedSize); // Avoid warning in release mode |
1144 | Q_UNUSED(buf); |
1145 | qsizetype size = 0; |
1146 | int dataIndex; |
1147 | int paramsIndex; |
1148 | int enumIndex; |
1149 | int index; |
1150 | bool hasRevisionedMethods = d->hasRevisionedMethods(); |
1151 | |
1152 | // Create the main QMetaObject structure at the start of the buffer. |
1153 | QMetaObject *meta = reinterpret_cast<QMetaObject *>(buf); |
1154 | size += sizeof(QMetaObject); |
1155 | ALIGN(size, int); |
1156 | if constexpr (mode == Construct) { |
1157 | meta->d.superdata = d->superClass; |
1158 | meta->d.relatedMetaObjects = nullptr; |
1159 | meta->d.extradata = nullptr; |
1160 | meta->d.metaTypes = nullptr; |
1161 | meta->d.static_metacall = d->staticMetacallFunction; |
1162 | } |
1163 | |
1164 | // Populate the QMetaObjectPrivate structure. |
1165 | QMetaObjectPrivate *pmeta |
1166 | = reinterpret_cast<QMetaObjectPrivate *>(buf + size); |
1167 | //int pmetaSize = size; |
1168 | dataIndex = MetaObjectPrivateFieldCount; |
1169 | int methodParametersDataSize = |
1170 | ((aggregateParameterCount(methods: d->methods) |
1171 | + aggregateParameterCount(methods: d->constructors)) * 2) // types and parameter names |
1172 | - int(d->methods.size()) // return "parameters" don't have names |
1173 | - int(d->constructors.size()); // "this" parameters don't have names |
1174 | if constexpr (mode == Construct) { |
1175 | static_assert(QMetaObjectPrivate::OutputRevision == 12, "QMetaObjectBuilder should generate the same version as moc" ); |
1176 | pmeta->revision = QMetaObjectPrivate::OutputRevision; |
1177 | pmeta->flags = d->flags.toInt(); |
1178 | pmeta->className = 0; // Class name is always the first string. |
1179 | //pmeta->signalCount is handled in the "output method loop" as an optimization. |
1180 | |
1181 | pmeta->classInfoCount = d->classInfoNames.size(); |
1182 | pmeta->classInfoData = dataIndex; |
1183 | dataIndex += 2 * d->classInfoNames.size(); |
1184 | |
1185 | pmeta->methodCount = int(d->methods.size()); |
1186 | pmeta->methodData = dataIndex; |
1187 | dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size()); |
1188 | if (hasRevisionedMethods) |
1189 | dataIndex += int(d->methods.size()); |
1190 | paramsIndex = dataIndex; |
1191 | dataIndex += methodParametersDataSize; |
1192 | |
1193 | pmeta->propertyCount = int(d->properties.size()); |
1194 | pmeta->propertyData = dataIndex; |
1195 | dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size()); |
1196 | |
1197 | pmeta->enumeratorCount = int(d->enumerators.size()); |
1198 | pmeta->enumeratorData = dataIndex; |
1199 | dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size()); |
1200 | |
1201 | pmeta->constructorCount = int(d->constructors.size()); |
1202 | pmeta->constructorData = dataIndex; |
1203 | dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size()); |
1204 | } else { |
1205 | dataIndex += 2 * int(d->classInfoNames.size()); |
1206 | dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->methods.size()); |
1207 | if (hasRevisionedMethods) |
1208 | dataIndex += int(d->methods.size()); |
1209 | paramsIndex = dataIndex; |
1210 | dataIndex += methodParametersDataSize; |
1211 | dataIndex += QMetaObjectPrivate::IntsPerProperty * int(d->properties.size()); |
1212 | dataIndex += QMetaObjectPrivate::IntsPerEnum * int(d->enumerators.size()); |
1213 | dataIndex += QMetaObjectPrivate::IntsPerMethod * int(d->constructors.size()); |
1214 | } |
1215 | |
1216 | // Allocate space for the enumerator key names and values. |
1217 | enumIndex = dataIndex; |
1218 | for (const auto &enumerator : d->enumerators) |
1219 | dataIndex += 2 * enumerator.keys.size(); |
1220 | |
1221 | // Zero terminator at the end of the data offset table. |
1222 | ++dataIndex; |
1223 | |
1224 | // Find the start of the data and string tables. |
1225 | int *data = reinterpret_cast<int *>(pmeta); |
1226 | size += dataIndex * sizeof(int); |
1227 | ALIGN(size, void *); |
1228 | [[maybe_unused]] char *str = reinterpret_cast<char *>(buf + size); |
1229 | if constexpr (mode == Construct) { |
1230 | meta->d.stringdata = reinterpret_cast<const uint *>(str); |
1231 | meta->d.data = reinterpret_cast<uint *>(data); |
1232 | } |
1233 | |
1234 | // Reset the current data position to just past the QMetaObjectPrivate. |
1235 | dataIndex = MetaObjectPrivateFieldCount; |
1236 | |
1237 | QMetaStringTable strings(d->className); |
1238 | |
1239 | // Output the class infos, |
1240 | Q_ASSERT(!buf || dataIndex == pmeta->classInfoData); |
1241 | for (index = 0; index < d->classInfoNames.size(); ++index) { |
1242 | [[maybe_unused]] int name = strings.enter(value: d->classInfoNames[index]); |
1243 | [[maybe_unused]] int value = strings.enter(value: d->classInfoValues[index]); |
1244 | if constexpr (mode == Construct) { |
1245 | data[dataIndex] = name; |
1246 | data[dataIndex + 1] = value; |
1247 | } |
1248 | dataIndex += 2; |
1249 | } |
1250 | |
1251 | // Output the methods in the class. |
1252 | Q_ASSERT(!buf || dataIndex == pmeta->methodData); |
1253 | // + 1 for metatype of this metaobject |
1254 | int parameterMetaTypesIndex = int(d->properties.size()) + 1; |
1255 | for (const auto &method : d->methods) { |
1256 | [[maybe_unused]] int name = strings.enter(value: method.name()); |
1257 | int argc = method.parameterCount(); |
1258 | [[maybe_unused]] int tag = strings.enter(value: method.tag); |
1259 | [[maybe_unused]] int attrs = method.attributes; |
1260 | if constexpr (mode == Construct) { |
1261 | data[dataIndex] = name; |
1262 | data[dataIndex + 1] = argc; |
1263 | data[dataIndex + 2] = paramsIndex; |
1264 | data[dataIndex + 3] = tag; |
1265 | data[dataIndex + 4] = attrs; |
1266 | data[dataIndex + 5] = parameterMetaTypesIndex; |
1267 | if (method.methodType() == QMetaMethod::Signal) |
1268 | pmeta->signalCount++; |
1269 | } |
1270 | dataIndex += QMetaObjectPrivate::IntsPerMethod; |
1271 | paramsIndex += 1 + argc * 2; |
1272 | parameterMetaTypesIndex += 1 + argc; |
1273 | } |
1274 | if (hasRevisionedMethods) { |
1275 | for (const auto &method : d->methods) { |
1276 | if constexpr (mode == Construct) |
1277 | data[dataIndex] = method.revision; |
1278 | ++dataIndex; |
1279 | } |
1280 | } |
1281 | |
1282 | // Output the method parameters in the class. |
1283 | Q_ASSERT(!buf || dataIndex == pmeta->methodData + int(d->methods.size()) * QMetaObjectPrivate::IntsPerMethod |
1284 | + (hasRevisionedMethods ? int(d->methods.size()) : 0)); |
1285 | for (int x = 0; x < 2; ++x) { |
1286 | const std::vector<QMetaMethodBuilderPrivate> &methods = (x == 0) ? d->methods : d->constructors; |
1287 | for (const auto &method : methods) { |
1288 | const QList<QByteArray> paramTypeNames = method.parameterTypes(); |
1289 | int paramCount = paramTypeNames.size(); |
1290 | for (int i = -1; i < paramCount; ++i) { |
1291 | const QByteArray &typeName = (i < 0) ? method.returnType : paramTypeNames.at(i); |
1292 | [[maybe_unused]] int typeInfo; |
1293 | if (QtPrivate::isBuiltinType(type: typeName)) |
1294 | typeInfo = QMetaType::fromName(name: typeName).id(); |
1295 | else |
1296 | typeInfo = IsUnresolvedType | strings.enter(value: typeName); |
1297 | if constexpr (mode == Construct) |
1298 | data[dataIndex] = typeInfo; |
1299 | ++dataIndex; |
1300 | } |
1301 | |
1302 | QList<QByteArray> paramNames = method.parameterNames; |
1303 | while (paramNames.size() < paramCount) |
1304 | paramNames.append(t: QByteArray()); |
1305 | for (int i = 0; i < paramCount; ++i) { |
1306 | [[maybe_unused]] int stringIndex = strings.enter(value: paramNames.at(i)); |
1307 | if constexpr (mode == Construct) |
1308 | data[dataIndex] = stringIndex; |
1309 | ++dataIndex; |
1310 | } |
1311 | } |
1312 | } |
1313 | |
1314 | // Output the properties in the class. |
1315 | Q_ASSERT(!buf || dataIndex == pmeta->propertyData); |
1316 | for (QMetaPropertyBuilderPrivate &prop : d->properties) { |
1317 | [[maybe_unused]] int name = strings.enter(value: prop.name); |
1318 | |
1319 | // try to resolve the metatype again if it was unknown |
1320 | if (!prop.metaType.isValid()) |
1321 | prop.metaType = QMetaType::fromName(name: prop.type); |
1322 | [[maybe_unused]] const int typeInfo = prop.metaType.isValid() |
1323 | ? prop.metaType.id() |
1324 | : IsUnresolvedType | strings.enter(value: prop.type); |
1325 | |
1326 | [[maybe_unused]] int flags = prop.flags; |
1327 | |
1328 | if (!QtPrivate::isBuiltinType(type: prop.type)) |
1329 | flags |= EnumOrFlag; |
1330 | |
1331 | if constexpr (mode == Construct) { |
1332 | data[dataIndex] = name; |
1333 | data[dataIndex + 1] = typeInfo; |
1334 | data[dataIndex + 2] = flags; |
1335 | data[dataIndex + 3] = prop.notifySignal; |
1336 | data[dataIndex + 4] = prop.revision; |
1337 | } |
1338 | dataIndex += QMetaObjectPrivate::IntsPerProperty; |
1339 | } |
1340 | |
1341 | // Output the enumerators in the class. |
1342 | Q_ASSERT(!buf || dataIndex == pmeta->enumeratorData); |
1343 | for (const auto &enumerator : d->enumerators) { |
1344 | [[maybe_unused]] int name = strings.enter(value: enumerator.name); |
1345 | [[maybe_unused]] int enumName = strings.enter(value: enumerator.enumName); |
1346 | [[maybe_unused]] int isFlag = enumerator.isFlag ? EnumIsFlag : 0; |
1347 | [[maybe_unused]] int isScoped = enumerator.isScoped ? EnumIsScoped : 0; |
1348 | int count = enumerator.keys.size(); |
1349 | int enumOffset = enumIndex; |
1350 | if constexpr (mode == Construct) { |
1351 | data[dataIndex] = name; |
1352 | data[dataIndex + 1] = enumName; |
1353 | data[dataIndex + 2] = isFlag | isScoped; |
1354 | data[dataIndex + 3] = count; |
1355 | data[dataIndex + 4] = enumOffset; |
1356 | } |
1357 | for (int key = 0; key < count; ++key) { |
1358 | [[maybe_unused]] int keyIndex = strings.enter(value: enumerator.keys[key]); |
1359 | if constexpr (mode == Construct) { |
1360 | data[enumOffset++] = keyIndex; |
1361 | data[enumOffset++] = enumerator.values[key]; |
1362 | } |
1363 | } |
1364 | dataIndex += QMetaObjectPrivate::IntsPerEnum; |
1365 | enumIndex += 2 * count; |
1366 | } |
1367 | |
1368 | // Output the constructors in the class. |
1369 | Q_ASSERT(!buf || dataIndex == pmeta->constructorData); |
1370 | for (const auto &ctor : d->constructors) { |
1371 | [[maybe_unused]] int name = strings.enter(value: ctor.name()); |
1372 | int argc = ctor.parameterCount(); |
1373 | [[maybe_unused]] int tag = strings.enter(value: ctor.tag); |
1374 | [[maybe_unused]] int attrs = ctor.attributes; |
1375 | if constexpr (mode == Construct) { |
1376 | data[dataIndex] = name; |
1377 | data[dataIndex + 1] = argc; |
1378 | data[dataIndex + 2] = paramsIndex; |
1379 | data[dataIndex + 3] = tag; |
1380 | data[dataIndex + 4] = attrs; |
1381 | data[dataIndex + 5] = parameterMetaTypesIndex; |
1382 | } |
1383 | dataIndex += QMetaObjectPrivate::IntsPerMethod; |
1384 | paramsIndex += 1 + argc * 2; |
1385 | parameterMetaTypesIndex += argc; |
1386 | } |
1387 | |
1388 | size += strings.blobSize(); |
1389 | |
1390 | if constexpr (mode == Construct) |
1391 | strings.writeBlob(out: str); |
1392 | |
1393 | // Output the zero terminator in the data array. |
1394 | if constexpr (mode == Construct) |
1395 | data[enumIndex] = 0; |
1396 | |
1397 | // Create the relatedMetaObjects block if we need one. |
1398 | if (d->relatedMetaObjects.size() > 0) { |
1399 | using SuperData = QMetaObject::SuperData; |
1400 | ALIGN(size, SuperData); |
1401 | auto objects = reinterpret_cast<SuperData *>(buf + size); |
1402 | if constexpr (mode == Construct) { |
1403 | meta->d.relatedMetaObjects = objects; |
1404 | for (index = 0; index < d->relatedMetaObjects.size(); ++index) |
1405 | objects[index] = d->relatedMetaObjects[index]; |
1406 | objects[index] = nullptr; |
1407 | } |
1408 | size += sizeof(SuperData) * (d->relatedMetaObjects.size() + 1); |
1409 | } |
1410 | |
1411 | ALIGN(size, QtPrivate::QMetaTypeInterface *); |
1412 | auto types = reinterpret_cast<QtPrivate::QMetaTypeInterface **>(buf + size); |
1413 | if constexpr (mode == Construct) { |
1414 | meta->d.metaTypes = types; |
1415 | for (const auto &prop : d->properties) { |
1416 | QMetaType mt = prop.metaType; |
1417 | *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); |
1418 | types++; |
1419 | } |
1420 | // add metatype interface for this metaobject - must be null |
1421 | // as we can't know our metatype |
1422 | *types = nullptr; |
1423 | types++; |
1424 | for (const auto &method: d->methods) { |
1425 | QMetaType mt(QMetaType::fromName(name: method.returnType).id()); |
1426 | *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); |
1427 | types++; |
1428 | for (const auto ¶meterType: method.parameterTypes()) { |
1429 | QMetaType mt = QMetaType::fromName(name: parameterType); |
1430 | *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); |
1431 | types++; |
1432 | } |
1433 | } |
1434 | for (const auto &constructor : d->constructors) { |
1435 | for (const auto ¶meterType : constructor.parameterTypes()) { |
1436 | QMetaType mt = QMetaType::fromName(name: parameterType); |
1437 | *types = reinterpret_cast<QtPrivate::QMetaTypeInterface *&>(mt); |
1438 | types++; |
1439 | } |
1440 | } |
1441 | } |
1442 | // parameterMetaTypesIndex is equal to the total number of metatypes |
1443 | size += sizeof(QMetaType) * parameterMetaTypesIndex; |
1444 | |
1445 | // Align the final size and return it. |
1446 | ALIGN(size, void *); |
1447 | Q_ASSERT(!buf || size == expectedSize); |
1448 | return size; |
1449 | } |
1450 | |
1451 | /*! |
1452 | Converts this meta object builder into a concrete QMetaObject. |
1453 | The return value should be deallocated using free() once it |
1454 | is no longer needed. |
1455 | |
1456 | The returned meta object is a snapshot of the state of the |
1457 | QMetaObjectBuilder. Any further modifications to the QMetaObjectBuilder |
1458 | will not be reflected in previous meta objects returned by |
1459 | this method. |
1460 | */ |
1461 | QMetaObject *QMetaObjectBuilder::toMetaObject() const |
1462 | { |
1463 | int size = buildMetaObject<Prepare>(d, buf: nullptr, expectedSize: 0); |
1464 | char *buf = reinterpret_cast<char *>(malloc(size: size)); |
1465 | memset(s: buf, c: 0, n: size); |
1466 | buildMetaObject<Construct>(d, buf, expectedSize: size); |
1467 | return reinterpret_cast<QMetaObject *>(buf); |
1468 | } |
1469 | |
1470 | /*! |
1471 | \typedef QMetaObjectBuilder::StaticMetacallFunction |
1472 | |
1473 | Typedef for static metacall functions. The three parameters are |
1474 | the call type value, the constructor index, and the |
1475 | array of parameters. |
1476 | */ |
1477 | |
1478 | /*! |
1479 | Returns the static metacall function to use to construct objects |
1480 | of this class. The default value is null. |
1481 | |
1482 | \sa setStaticMetacallFunction() |
1483 | */ |
1484 | QMetaObjectBuilder::StaticMetacallFunction QMetaObjectBuilder::staticMetacallFunction() const |
1485 | { |
1486 | return d->staticMetacallFunction; |
1487 | } |
1488 | |
1489 | /*! |
1490 | Sets the static metacall function to use to construct objects |
1491 | of this class to \a value. The default value is null. |
1492 | |
1493 | \sa staticMetacallFunction() |
1494 | */ |
1495 | void QMetaObjectBuilder::setStaticMetacallFunction |
1496 | (QMetaObjectBuilder::StaticMetacallFunction value) |
1497 | { |
1498 | d->staticMetacallFunction = value; |
1499 | } |
1500 | |
1501 | /*! |
1502 | \class QMetaMethodBuilder |
1503 | \inmodule QtCore |
1504 | \internal |
1505 | \brief The QMetaMethodBuilder class enables modifications to a method definition on a meta object builder. |
1506 | */ |
1507 | |
1508 | QMetaMethodBuilderPrivate *QMetaMethodBuilder::d_func() const |
1509 | { |
1510 | // Positive indices indicate methods, negative indices indicate constructors. |
1511 | if (_mobj && _index >= 0 && _index < int(_mobj->d->methods.size())) |
1512 | return &(_mobj->d->methods[_index]); |
1513 | else if (_mobj && -_index >= 1 && -_index <= int(_mobj->d->constructors.size())) |
1514 | return &(_mobj->d->constructors[(-_index) - 1]); |
1515 | else |
1516 | return nullptr; |
1517 | } |
1518 | |
1519 | /*! |
1520 | \fn QMetaMethodBuilder::QMetaMethodBuilder() |
1521 | \internal |
1522 | */ |
1523 | |
1524 | /*! |
1525 | Returns the index of this method within its QMetaObjectBuilder. |
1526 | */ |
1527 | int QMetaMethodBuilder::index() const |
1528 | { |
1529 | if (_index >= 0) |
1530 | return _index; // Method, signal, or slot |
1531 | else |
1532 | return (-_index) - 1; // Constructor |
1533 | } |
1534 | |
1535 | /*! |
1536 | Returns the type of this method (signal, slot, method, or constructor). |
1537 | */ |
1538 | QMetaMethod::MethodType QMetaMethodBuilder::methodType() const |
1539 | { |
1540 | QMetaMethodBuilderPrivate *d = d_func(); |
1541 | if (d) |
1542 | return d->methodType(); |
1543 | else |
1544 | return QMetaMethod::Method; |
1545 | } |
1546 | |
1547 | /*! |
1548 | Returns the signature of this method. |
1549 | |
1550 | \sa parameterNames(), returnType() |
1551 | */ |
1552 | QByteArray QMetaMethodBuilder::signature() const |
1553 | { |
1554 | QMetaMethodBuilderPrivate *d = d_func(); |
1555 | if (d) |
1556 | return d->signature; |
1557 | else |
1558 | return QByteArray(); |
1559 | } |
1560 | |
1561 | /*! |
1562 | Returns the return type for this method; empty if the method's |
1563 | return type is \c{void}. |
1564 | |
1565 | \sa setReturnType(), signature() |
1566 | */ |
1567 | QByteArray QMetaMethodBuilder::returnType() const |
1568 | { |
1569 | QMetaMethodBuilderPrivate *d = d_func(); |
1570 | if (d) |
1571 | return d->returnType; |
1572 | else |
1573 | return QByteArray(); |
1574 | } |
1575 | |
1576 | /*! |
1577 | Sets the return type for this method to \a value. If \a value |
1578 | is empty, then the method's return type is \c{void}. The \a value |
1579 | will be normalized before it is added to the method. |
1580 | |
1581 | \sa returnType(), parameterTypes(), signature() |
1582 | */ |
1583 | void QMetaMethodBuilder::setReturnType(const QByteArray &value) |
1584 | { |
1585 | QMetaMethodBuilderPrivate *d = d_func(); |
1586 | if (d) |
1587 | d->returnType = QMetaObject::normalizedType(type: value); |
1588 | } |
1589 | |
1590 | /*! |
1591 | Returns the list of parameter types for this method. |
1592 | |
1593 | \sa returnType(), parameterNames() |
1594 | */ |
1595 | QList<QByteArray> QMetaMethodBuilder::parameterTypes() const |
1596 | { |
1597 | QMetaMethodBuilderPrivate *d = d_func(); |
1598 | if (d) |
1599 | return d->parameterTypes(); |
1600 | else |
1601 | return QList<QByteArray>(); |
1602 | } |
1603 | |
1604 | /*! |
1605 | Returns the list of parameter names for this method. |
1606 | |
1607 | \sa setParameterNames() |
1608 | */ |
1609 | QList<QByteArray> QMetaMethodBuilder::parameterNames() const |
1610 | { |
1611 | QMetaMethodBuilderPrivate *d = d_func(); |
1612 | if (d) |
1613 | return d->parameterNames; |
1614 | else |
1615 | return QList<QByteArray>(); |
1616 | } |
1617 | |
1618 | /*! |
1619 | Sets the list of parameter names for this method to \a value. |
1620 | |
1621 | \sa parameterNames() |
1622 | */ |
1623 | void QMetaMethodBuilder::setParameterNames(const QList<QByteArray> &value) |
1624 | { |
1625 | QMetaMethodBuilderPrivate *d = d_func(); |
1626 | if (d) |
1627 | d->parameterNames = value; |
1628 | } |
1629 | |
1630 | /*! |
1631 | Returns the tag associated with this method. |
1632 | |
1633 | \sa setTag() |
1634 | */ |
1635 | QByteArray QMetaMethodBuilder::tag() const |
1636 | { |
1637 | QMetaMethodBuilderPrivate *d = d_func(); |
1638 | if (d) |
1639 | return d->tag; |
1640 | else |
1641 | return QByteArray(); |
1642 | } |
1643 | |
1644 | /*! |
1645 | Sets the tag associated with this method to \a value. |
1646 | |
1647 | \sa setTag() |
1648 | */ |
1649 | void QMetaMethodBuilder::setTag(const QByteArray &value) |
1650 | { |
1651 | QMetaMethodBuilderPrivate *d = d_func(); |
1652 | if (d) |
1653 | d->tag = value; |
1654 | } |
1655 | |
1656 | /*! |
1657 | Returns the access specification of this method (private, protected, |
1658 | or public). The default value is QMetaMethod::Public for methods, |
1659 | slots, signals and constructors. |
1660 | |
1661 | \sa setAccess() |
1662 | */ |
1663 | QMetaMethod::Access QMetaMethodBuilder::access() const |
1664 | { |
1665 | QMetaMethodBuilderPrivate *d = d_func(); |
1666 | if (d) |
1667 | return d->access(); |
1668 | else |
1669 | return QMetaMethod::Public; |
1670 | } |
1671 | |
1672 | /*! |
1673 | Sets the access specification of this method (private, protected, |
1674 | or public) to \a value. If the method is a signal, this function |
1675 | will be ignored. |
1676 | |
1677 | \sa access() |
1678 | */ |
1679 | void QMetaMethodBuilder::setAccess(QMetaMethod::Access value) |
1680 | { |
1681 | QMetaMethodBuilderPrivate *d = d_func(); |
1682 | if (d && d->methodType() != QMetaMethod::Signal) |
1683 | d->setAccess(value); |
1684 | } |
1685 | |
1686 | /*! |
1687 | Returns the additional attributes for this method. |
1688 | |
1689 | \sa setAttributes() |
1690 | */ |
1691 | int QMetaMethodBuilder::attributes() const |
1692 | { |
1693 | QMetaMethodBuilderPrivate *d = d_func(); |
1694 | if (d) |
1695 | return (d->attributes >> 4); |
1696 | else |
1697 | return 0; |
1698 | } |
1699 | |
1700 | /*! |
1701 | Sets the additional attributes for this method to \a value. |
1702 | |
1703 | \sa attributes() |
1704 | */ |
1705 | void QMetaMethodBuilder::setAttributes(int value) |
1706 | { |
1707 | QMetaMethodBuilderPrivate *d = d_func(); |
1708 | if (d) |
1709 | d->attributes = ((d->attributes & 0x0f) | (value << 4)); |
1710 | } |
1711 | |
1712 | /*! |
1713 | Returns true if the method is const qualified. |
1714 | */ |
1715 | int QMetaMethodBuilder::isConst() const |
1716 | { |
1717 | QMetaMethodBuilderPrivate *d = d_func(); |
1718 | if (!d) |
1719 | return false; |
1720 | return (d->attributes & MethodIsConst); |
1721 | } |
1722 | |
1723 | void QMetaMethodBuilder::setConst(bool methodIsConst) |
1724 | { |
1725 | QMetaMethodBuilderPrivate *d = d_func(); |
1726 | if (!d) |
1727 | return; |
1728 | if (methodIsConst) |
1729 | d->attributes |= MethodIsConst; |
1730 | else |
1731 | d->attributes &= ~MethodIsConst; |
1732 | } |
1733 | |
1734 | /*! |
1735 | Returns the revision of this method. |
1736 | |
1737 | \sa setRevision() |
1738 | */ |
1739 | int QMetaMethodBuilder::revision() const |
1740 | { |
1741 | QMetaMethodBuilderPrivate *d = d_func(); |
1742 | if (d) |
1743 | return d->revision; |
1744 | return 0; |
1745 | } |
1746 | |
1747 | /*! |
1748 | Sets the \a revision of this method. |
1749 | |
1750 | \sa revision() |
1751 | */ |
1752 | void QMetaMethodBuilder::setRevision(int revision) |
1753 | { |
1754 | QMetaMethodBuilderPrivate *d = d_func(); |
1755 | if (d) { |
1756 | d->revision = revision; |
1757 | if (revision) |
1758 | d->attributes |= MethodRevisioned; |
1759 | else |
1760 | d->attributes &= ~MethodRevisioned; |
1761 | } |
1762 | } |
1763 | |
1764 | /*! |
1765 | \class QMetaPropertyBuilder |
1766 | \inmodule QtCore |
1767 | \internal |
1768 | \brief The QMetaPropertyBuilder class enables modifications to a property definition on a meta object builder. |
1769 | */ |
1770 | |
1771 | QMetaPropertyBuilderPrivate *QMetaPropertyBuilder::d_func() const |
1772 | { |
1773 | if (_mobj && _index >= 0 && _index < int(_mobj->d->properties.size())) |
1774 | return &(_mobj->d->properties[_index]); |
1775 | else |
1776 | return nullptr; |
1777 | } |
1778 | |
1779 | /*! |
1780 | \fn QMetaPropertyBuilder::QMetaPropertyBuilder() |
1781 | \internal |
1782 | */ |
1783 | |
1784 | /*! |
1785 | \fn int QMetaPropertyBuilder::index() const |
1786 | |
1787 | Returns the index of this property within its QMetaObjectBuilder. |
1788 | */ |
1789 | |
1790 | /*! |
1791 | Returns the name associated with this property. |
1792 | |
1793 | \sa type() |
1794 | */ |
1795 | QByteArray QMetaPropertyBuilder::name() const |
1796 | { |
1797 | QMetaPropertyBuilderPrivate *d = d_func(); |
1798 | if (d) |
1799 | return d->name; |
1800 | else |
1801 | return QByteArray(); |
1802 | } |
1803 | |
1804 | /*! |
1805 | Returns the type associated with this property. |
1806 | |
1807 | \sa name() |
1808 | */ |
1809 | QByteArray QMetaPropertyBuilder::type() const |
1810 | { |
1811 | QMetaPropertyBuilderPrivate *d = d_func(); |
1812 | if (d) |
1813 | return d->type; |
1814 | else |
1815 | return QByteArray(); |
1816 | } |
1817 | |
1818 | /*! |
1819 | Returns \c true if this property has a notify signal; false otherwise. |
1820 | |
1821 | \sa notifySignal(), setNotifySignal(), removeNotifySignal() |
1822 | */ |
1823 | bool QMetaPropertyBuilder::hasNotifySignal() const |
1824 | { |
1825 | QMetaPropertyBuilderPrivate *d = d_func(); |
1826 | if (d) |
1827 | return d->notifySignal != -1; |
1828 | else |
1829 | return false; |
1830 | } |
1831 | |
1832 | /*! |
1833 | Returns the notify signal associated with this property. |
1834 | |
1835 | \sa hasNotifySignal(), setNotifySignal(), removeNotifySignal() |
1836 | */ |
1837 | QMetaMethodBuilder QMetaPropertyBuilder::notifySignal() const |
1838 | { |
1839 | QMetaPropertyBuilderPrivate *d = d_func(); |
1840 | if (d && d->notifySignal >= 0) |
1841 | return QMetaMethodBuilder(_mobj, d->notifySignal); |
1842 | else |
1843 | return QMetaMethodBuilder(); |
1844 | } |
1845 | |
1846 | /*! |
1847 | Sets the notify signal associated with this property to \a value. |
1848 | |
1849 | \sa hasNotifySignal(), notifySignal(), removeNotifySignal() |
1850 | */ |
1851 | void QMetaPropertyBuilder::setNotifySignal(const QMetaMethodBuilder &value) |
1852 | { |
1853 | QMetaPropertyBuilderPrivate *d = d_func(); |
1854 | if (d) { |
1855 | if (value._mobj) { |
1856 | d->notifySignal = value._index; |
1857 | } else { |
1858 | d->notifySignal = -1; |
1859 | } |
1860 | } |
1861 | } |
1862 | |
1863 | /*! |
1864 | Removes the notify signal from this property. |
1865 | |
1866 | \sa hasNotifySignal(), notifySignal(), setNotifySignal() |
1867 | */ |
1868 | void QMetaPropertyBuilder::removeNotifySignal() |
1869 | { |
1870 | QMetaPropertyBuilderPrivate *d = d_func(); |
1871 | if (d) |
1872 | d->notifySignal = -1; |
1873 | } |
1874 | |
1875 | /*! |
1876 | Returns \c true if this property is readable; otherwise returns \c false. |
1877 | The default value is true. |
1878 | |
1879 | \sa setReadable(), isWritable() |
1880 | */ |
1881 | bool QMetaPropertyBuilder::isReadable() const |
1882 | { |
1883 | QMetaPropertyBuilderPrivate *d = d_func(); |
1884 | if (d) |
1885 | return d->flag(f: Readable); |
1886 | else |
1887 | return false; |
1888 | } |
1889 | |
1890 | /*! |
1891 | Returns \c true if this property is writable; otherwise returns \c false. |
1892 | The default value is true. |
1893 | |
1894 | \sa setWritable(), isReadable() |
1895 | */ |
1896 | bool QMetaPropertyBuilder::isWritable() const |
1897 | { |
1898 | QMetaPropertyBuilderPrivate *d = d_func(); |
1899 | if (d) |
1900 | return d->flag(f: Writable); |
1901 | else |
1902 | return false; |
1903 | } |
1904 | |
1905 | /*! |
1906 | Returns \c true if this property can be reset to a default value; otherwise |
1907 | returns \c false. The default value is false. |
1908 | |
1909 | \sa setResettable() |
1910 | */ |
1911 | bool QMetaPropertyBuilder::isResettable() const |
1912 | { |
1913 | QMetaPropertyBuilderPrivate *d = d_func(); |
1914 | if (d) |
1915 | return d->flag(f: Resettable); |
1916 | else |
1917 | return false; |
1918 | } |
1919 | |
1920 | /*! |
1921 | Returns \c true if this property is designable; otherwise returns \c false. |
1922 | This default value is false. |
1923 | |
1924 | \sa setDesignable(), isScriptable(), isStored() |
1925 | */ |
1926 | bool QMetaPropertyBuilder::isDesignable() const |
1927 | { |
1928 | QMetaPropertyBuilderPrivate *d = d_func(); |
1929 | if (d) |
1930 | return d->flag(f: Designable); |
1931 | else |
1932 | return false; |
1933 | } |
1934 | |
1935 | /*! |
1936 | Returns \c true if the property is scriptable; otherwise returns \c false. |
1937 | This default value is true. |
1938 | |
1939 | \sa setScriptable(), isDesignable(), isStored() |
1940 | */ |
1941 | bool QMetaPropertyBuilder::isScriptable() const |
1942 | { |
1943 | QMetaPropertyBuilderPrivate *d = d_func(); |
1944 | if (d) |
1945 | return d->flag(f: Scriptable); |
1946 | else |
1947 | return false; |
1948 | } |
1949 | |
1950 | /*! |
1951 | Returns \c true if the property is stored; otherwise returns \c false. |
1952 | This default value is false. |
1953 | |
1954 | \sa setStored(), isDesignable(), isScriptable() |
1955 | */ |
1956 | bool QMetaPropertyBuilder::isStored() const |
1957 | { |
1958 | QMetaPropertyBuilderPrivate *d = d_func(); |
1959 | if (d) |
1960 | return d->flag(f: Stored); |
1961 | else |
1962 | return false; |
1963 | } |
1964 | |
1965 | /*! |
1966 | Returns \c true if this property is designated as the \c USER |
1967 | property, i.e., the one that the user can edit or that is |
1968 | significant in some other way. Otherwise it returns |
1969 | false. This default value is false. |
1970 | |
1971 | \sa setUser(), isDesignable(), isScriptable() |
1972 | */ |
1973 | bool QMetaPropertyBuilder::isUser() const |
1974 | { |
1975 | QMetaPropertyBuilderPrivate *d = d_func(); |
1976 | if (d) |
1977 | return d->flag(f: User); |
1978 | else |
1979 | return false; |
1980 | } |
1981 | |
1982 | /*! |
1983 | Returns \c true if the property has a C++ setter function that |
1984 | follows Qt's standard "name" / "setName" pattern. Designer and uic |
1985 | query hasStdCppSet() in order to avoid expensive |
1986 | QObject::setProperty() calls. All properties in Qt [should] follow |
1987 | this pattern. The default value is false. |
1988 | |
1989 | \sa setStdCppSet() |
1990 | */ |
1991 | bool QMetaPropertyBuilder::hasStdCppSet() const |
1992 | { |
1993 | QMetaPropertyBuilderPrivate *d = d_func(); |
1994 | if (d) |
1995 | return d->flag(f: StdCppSet); |
1996 | else |
1997 | return false; |
1998 | } |
1999 | |
2000 | /*! |
2001 | Returns \c true if the property is an enumerator or flag type; |
2002 | otherwise returns \c false. This default value is false. |
2003 | |
2004 | \sa setEnumOrFlag() |
2005 | */ |
2006 | bool QMetaPropertyBuilder::isEnumOrFlag() const |
2007 | { |
2008 | QMetaPropertyBuilderPrivate *d = d_func(); |
2009 | if (d) |
2010 | return d->flag(f: EnumOrFlag); |
2011 | else |
2012 | return false; |
2013 | } |
2014 | |
2015 | /*! |
2016 | Returns \c true if the property is constant; otherwise returns \c false. |
2017 | The default value is false. |
2018 | */ |
2019 | bool QMetaPropertyBuilder::isConstant() const |
2020 | { |
2021 | QMetaPropertyBuilderPrivate *d = d_func(); |
2022 | if (d) |
2023 | return d->flag(f: Constant); |
2024 | else |
2025 | return false; |
2026 | } |
2027 | |
2028 | /*! |
2029 | Returns \c true if the property is final; otherwise returns \c false. |
2030 | The default value is false. |
2031 | */ |
2032 | bool QMetaPropertyBuilder::isFinal() const |
2033 | { |
2034 | QMetaPropertyBuilderPrivate *d = d_func(); |
2035 | if (d) |
2036 | return d->flag(f: Final); |
2037 | else |
2038 | return false; |
2039 | } |
2040 | |
2041 | /*! |
2042 | * Returns \c true if the property is an alias. |
2043 | * The default value is false |
2044 | */ |
2045 | bool QMetaPropertyBuilder::isAlias() const |
2046 | { |
2047 | QMetaPropertyBuilderPrivate *d = d_func(); |
2048 | if (d) |
2049 | return d->flag(f: Alias); |
2050 | else |
2051 | return false; |
2052 | } |
2053 | |
2054 | /*! |
2055 | Returns \c true if the property is bindable |
2056 | The default value is false |
2057 | */ |
2058 | bool QMetaPropertyBuilder::isBindable() const |
2059 | { |
2060 | if (auto d = d_func()) |
2061 | return d->flag(f: Bindable); |
2062 | else |
2063 | return false; |
2064 | } |
2065 | |
2066 | /*! |
2067 | Sets this property to readable if \a value is true. |
2068 | |
2069 | \sa isReadable(), setWritable() |
2070 | */ |
2071 | void QMetaPropertyBuilder::setReadable(bool value) |
2072 | { |
2073 | QMetaPropertyBuilderPrivate *d = d_func(); |
2074 | if (d) |
2075 | d->setFlag(f: Readable, value); |
2076 | } |
2077 | |
2078 | /*! |
2079 | Sets this property to writable if \a value is true. |
2080 | |
2081 | \sa isWritable(), setReadable() |
2082 | */ |
2083 | void QMetaPropertyBuilder::setWritable(bool value) |
2084 | { |
2085 | QMetaPropertyBuilderPrivate *d = d_func(); |
2086 | if (d) |
2087 | d->setFlag(f: Writable, value); |
2088 | } |
2089 | |
2090 | /*! |
2091 | Sets this property to resettable if \a value is true. |
2092 | |
2093 | \sa isResettable() |
2094 | */ |
2095 | void QMetaPropertyBuilder::setResettable(bool value) |
2096 | { |
2097 | QMetaPropertyBuilderPrivate *d = d_func(); |
2098 | if (d) |
2099 | d->setFlag(f: Resettable, value); |
2100 | } |
2101 | |
2102 | /*! |
2103 | Sets this property to designable if \a value is true. |
2104 | |
2105 | \sa isDesignable(), setScriptable(), setStored() |
2106 | */ |
2107 | void QMetaPropertyBuilder::setDesignable(bool value) |
2108 | { |
2109 | QMetaPropertyBuilderPrivate *d = d_func(); |
2110 | if (d) |
2111 | d->setFlag(f: Designable, value); |
2112 | } |
2113 | |
2114 | /*! |
2115 | Sets this property to scriptable if \a value is true. |
2116 | |
2117 | \sa isScriptable(), setDesignable(), setStored() |
2118 | */ |
2119 | void QMetaPropertyBuilder::setScriptable(bool value) |
2120 | { |
2121 | QMetaPropertyBuilderPrivate *d = d_func(); |
2122 | if (d) |
2123 | d->setFlag(f: Scriptable, value); |
2124 | } |
2125 | |
2126 | /*! |
2127 | Sets this property to storable if \a value is true. |
2128 | |
2129 | \sa isStored(), setDesignable(), setScriptable() |
2130 | */ |
2131 | void QMetaPropertyBuilder::setStored(bool value) |
2132 | { |
2133 | QMetaPropertyBuilderPrivate *d = d_func(); |
2134 | if (d) |
2135 | d->setFlag(f: Stored, value); |
2136 | } |
2137 | |
2138 | /*! |
2139 | Sets the \c USER flag on this property to \a value. |
2140 | |
2141 | \sa isUser(), setDesignable(), setScriptable() |
2142 | */ |
2143 | void QMetaPropertyBuilder::setUser(bool value) |
2144 | { |
2145 | QMetaPropertyBuilderPrivate *d = d_func(); |
2146 | if (d) |
2147 | d->setFlag(f: User, value); |
2148 | } |
2149 | |
2150 | /*! |
2151 | Sets the C++ setter flag on this property to \a value, which is |
2152 | true if the property has a C++ setter function that follows Qt's |
2153 | standard "name" / "setName" pattern. |
2154 | |
2155 | \sa hasStdCppSet() |
2156 | */ |
2157 | void QMetaPropertyBuilder::setStdCppSet(bool value) |
2158 | { |
2159 | QMetaPropertyBuilderPrivate *d = d_func(); |
2160 | if (d) |
2161 | d->setFlag(f: StdCppSet, value); |
2162 | } |
2163 | |
2164 | /*! |
2165 | Sets this property to be of an enumerator or flag type if |
2166 | \a value is true. |
2167 | |
2168 | \sa isEnumOrFlag() |
2169 | */ |
2170 | void QMetaPropertyBuilder::setEnumOrFlag(bool value) |
2171 | { |
2172 | QMetaPropertyBuilderPrivate *d = d_func(); |
2173 | if (d) |
2174 | d->setFlag(f: EnumOrFlag, value); |
2175 | } |
2176 | |
2177 | /*! |
2178 | Sets the \c CONSTANT flag on this property to \a value. |
2179 | |
2180 | \sa isConstant() |
2181 | */ |
2182 | void QMetaPropertyBuilder::setConstant(bool value) |
2183 | { |
2184 | QMetaPropertyBuilderPrivate *d = d_func(); |
2185 | if (d) |
2186 | d->setFlag(f: Constant, value); |
2187 | } |
2188 | |
2189 | /*! |
2190 | Sets the \c FINAL flag on this property to \a value. |
2191 | |
2192 | \sa isFinal() |
2193 | */ |
2194 | void QMetaPropertyBuilder::setFinal(bool value) |
2195 | { |
2196 | QMetaPropertyBuilderPrivate *d = d_func(); |
2197 | if (d) |
2198 | d->setFlag(f: Final, value); |
2199 | } |
2200 | |
2201 | /*! |
2202 | Sets the \c ALIAS flag on this property to \a value |
2203 | */ |
2204 | void QMetaPropertyBuilder::setAlias(bool value) |
2205 | { |
2206 | QMetaPropertyBuilderPrivate *d = d_func(); |
2207 | if (d) |
2208 | d->setFlag(f: Alias, value); |
2209 | } |
2210 | |
2211 | /*! |
2212 | Sets the\c BINDABLE flag on this property to \a value |
2213 | */ |
2214 | void QMetaPropertyBuilder::setBindable(bool value) |
2215 | { |
2216 | if (auto d = d_func()) |
2217 | d->setFlag(f: Bindable, value); |
2218 | } |
2219 | |
2220 | /*! |
2221 | Returns the revision of this property. |
2222 | |
2223 | \sa setRevision() |
2224 | */ |
2225 | int QMetaPropertyBuilder::revision() const |
2226 | { |
2227 | QMetaPropertyBuilderPrivate *d = d_func(); |
2228 | if (d) |
2229 | return d->revision; |
2230 | return 0; |
2231 | } |
2232 | |
2233 | /*! |
2234 | Sets the \a revision of this property. |
2235 | |
2236 | \sa revision() |
2237 | */ |
2238 | void QMetaPropertyBuilder::setRevision(int revision) |
2239 | { |
2240 | QMetaPropertyBuilderPrivate *d = d_func(); |
2241 | if (d) |
2242 | d->revision = revision; |
2243 | } |
2244 | |
2245 | /*! |
2246 | \class QMetaEnumBuilder |
2247 | \inmodule QtCore |
2248 | \internal |
2249 | \brief The QMetaEnumBuilder class enables modifications to an enumerator definition on a meta object builder. |
2250 | */ |
2251 | |
2252 | QMetaEnumBuilderPrivate *QMetaEnumBuilder::d_func() const |
2253 | { |
2254 | if (_mobj && _index >= 0 && _index < int(_mobj->d->enumerators.size())) |
2255 | return &(_mobj->d->enumerators[_index]); |
2256 | else |
2257 | return nullptr; |
2258 | } |
2259 | |
2260 | /*! |
2261 | \fn QMetaEnumBuilder::QMetaEnumBuilder() |
2262 | \internal |
2263 | */ |
2264 | |
2265 | /*! |
2266 | \fn int QMetaEnumBuilder::index() const |
2267 | |
2268 | Returns the index of this enumerator within its QMetaObjectBuilder. |
2269 | */ |
2270 | |
2271 | /*! |
2272 | Returns the type name of the enumerator (without the scope). |
2273 | */ |
2274 | QByteArray QMetaEnumBuilder::name() const |
2275 | { |
2276 | QMetaEnumBuilderPrivate *d = d_func(); |
2277 | if (d) |
2278 | return d->name; |
2279 | else |
2280 | return QByteArray(); |
2281 | } |
2282 | |
2283 | /*! |
2284 | Returns the enum name of the enumerator (without the scope). |
2285 | |
2286 | \since 5.12 |
2287 | */ |
2288 | QByteArray QMetaEnumBuilder::enumName() const |
2289 | { |
2290 | QMetaEnumBuilderPrivate *d = d_func(); |
2291 | if (d) |
2292 | return d->enumName; |
2293 | else |
2294 | return QByteArray(); |
2295 | } |
2296 | |
2297 | /*! |
2298 | Sets this enumerator to have the enum name \c alias. |
2299 | |
2300 | \since 5.12 |
2301 | \sa isFlag(), enumName() |
2302 | */ |
2303 | void QMetaEnumBuilder::setEnumName(const QByteArray &alias) |
2304 | { |
2305 | QMetaEnumBuilderPrivate *d = d_func(); |
2306 | if (d) |
2307 | d->enumName = alias; |
2308 | } |
2309 | |
2310 | /*! |
2311 | Returns the meta type of the enumerator. |
2312 | |
2313 | \since 6.6 |
2314 | */ |
2315 | QMetaType QMetaEnumBuilder::metaType() const |
2316 | { |
2317 | if (QMetaEnumBuilderPrivate *d = d_func()) |
2318 | return d->metaType; |
2319 | return QMetaType(); |
2320 | } |
2321 | |
2322 | /*! |
2323 | Sets this enumerator to have the given \c metaType. |
2324 | |
2325 | \since 6.6 |
2326 | \sa metaType() |
2327 | */ |
2328 | void QMetaEnumBuilder::setMetaType(QMetaType metaType) |
2329 | { |
2330 | QMetaEnumBuilderPrivate *d = d_func(); |
2331 | if (d) |
2332 | d->metaType = metaType; |
2333 | } |
2334 | |
2335 | /*! |
2336 | Returns \c true if this enumerator is used as a flag; otherwise returns |
2337 | false. |
2338 | |
2339 | \sa setIsFlag() |
2340 | */ |
2341 | bool QMetaEnumBuilder::isFlag() const |
2342 | { |
2343 | QMetaEnumBuilderPrivate *d = d_func(); |
2344 | if (d) |
2345 | return d->isFlag; |
2346 | else |
2347 | return false; |
2348 | } |
2349 | |
2350 | /*! |
2351 | Sets this enumerator to be used as a flag if \a value is true. |
2352 | |
2353 | \sa isFlag() |
2354 | */ |
2355 | void QMetaEnumBuilder::setIsFlag(bool value) |
2356 | { |
2357 | QMetaEnumBuilderPrivate *d = d_func(); |
2358 | if (d) |
2359 | d->isFlag = value; |
2360 | } |
2361 | |
2362 | /*! |
2363 | Return \c true if this enumerator should be considered scoped (C++11 enum class). |
2364 | |
2365 | \sa setIsScoped() |
2366 | */ |
2367 | bool QMetaEnumBuilder::isScoped() const |
2368 | { |
2369 | QMetaEnumBuilderPrivate *d = d_func(); |
2370 | if (d) |
2371 | return d->isScoped; |
2372 | return false; |
2373 | } |
2374 | |
2375 | /*! |
2376 | Sets this enumerator to be a scoped enum if \value is true |
2377 | |
2378 | \sa isScoped() |
2379 | */ |
2380 | void QMetaEnumBuilder::setIsScoped(bool value) |
2381 | { |
2382 | QMetaEnumBuilderPrivate *d = d_func(); |
2383 | if (d) |
2384 | d->isScoped = value; |
2385 | } |
2386 | |
2387 | /*! |
2388 | Returns the number of keys. |
2389 | |
2390 | \sa key(), addKey() |
2391 | */ |
2392 | int QMetaEnumBuilder::keyCount() const |
2393 | { |
2394 | QMetaEnumBuilderPrivate *d = d_func(); |
2395 | if (d) |
2396 | return d->keys.size(); |
2397 | else |
2398 | return 0; |
2399 | } |
2400 | |
2401 | /*! |
2402 | Returns the key with the given \a index, or an empty QByteArray |
2403 | if no such key exists. |
2404 | |
2405 | \sa keyCount(), addKey(), value() |
2406 | */ |
2407 | QByteArray QMetaEnumBuilder::key(int index) const |
2408 | { |
2409 | QMetaEnumBuilderPrivate *d = d_func(); |
2410 | if (d && index >= 0 && index < d->keys.size()) |
2411 | return d->keys[index]; |
2412 | else |
2413 | return QByteArray(); |
2414 | } |
2415 | |
2416 | /*! |
2417 | Returns the value with the given \a index; or returns -1 if there |
2418 | is no such value. |
2419 | |
2420 | \sa keyCount(), addKey(), key() |
2421 | */ |
2422 | int QMetaEnumBuilder::value(int index) const |
2423 | { |
2424 | QMetaEnumBuilderPrivate *d = d_func(); |
2425 | if (d && index >= 0 && index < d->keys.size()) |
2426 | return d->values[index]; |
2427 | else |
2428 | return -1; |
2429 | } |
2430 | |
2431 | /*! |
2432 | Adds a new key called \a name to this enumerator, associated |
2433 | with \a value. Returns the index of the new key. |
2434 | |
2435 | \sa keyCount(), key(), value(), removeKey() |
2436 | */ |
2437 | int QMetaEnumBuilder::addKey(const QByteArray &name, int value) |
2438 | { |
2439 | QMetaEnumBuilderPrivate *d = d_func(); |
2440 | if (d) { |
2441 | int index = d->keys.size(); |
2442 | d->keys += name; |
2443 | d->values += value; |
2444 | return index; |
2445 | } else { |
2446 | return -1; |
2447 | } |
2448 | } |
2449 | |
2450 | /*! |
2451 | Removes the key at \a index from this enumerator. |
2452 | |
2453 | \sa addKey() |
2454 | */ |
2455 | void QMetaEnumBuilder::removeKey(int index) |
2456 | { |
2457 | QMetaEnumBuilderPrivate *d = d_func(); |
2458 | if (d && index >= 0 && index < d->keys.size()) { |
2459 | d->keys.removeAt(i: index); |
2460 | d->values.removeAt(i: index); |
2461 | } |
2462 | } |
2463 | |
2464 | QT_END_NAMESPACE |
2465 | |