Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qqmlsa.cpp
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant
4
5#include "qqmlsa.h"
6#include "qqmlsa_p.h"
8
10#include "qqmljslogger_p.h"
13#include "qqmljsutils_p.h"
15
16#include <QtQmlCompiler/private/qqmlsasourcelocation_p.h>
17
18#include <memory>
19
21
22using namespace Qt::StringLiterals;
23
24namespace QQmlSA {
25
26static_assert(QQmlJSScope::sizeofQQmlSAElement() == sizeof(Element));
27
28/*!
29 \namespace QQmlSA
30 \inmodule QtQmlCompiler
31
32 \brief Provides tools for static analysis on QML programs.
33 */
34
35/*!
36 \enum QQmlSA::MethodType
37 \inmodule QtQmlCompiler
38
39 \brief Describes the type of a \l{QQmlSA::Method}.
40 \value Signal The method is a signal
41 \value Slot The method is a slot
42 \value Method The method is a \l{Q_INVOKABLE} method
43 \value StaticMethod The method is a \l{Q_INVOKABLE} static method
44*/
45
46/*!
47 \enum QQmlSA::AccessSemantics
48 \inmodule QtQmlCompiler
49
50 \brief Describes how a type is accessed and shared.
51 \value Reference The type behaves like an \l{QML Object Types}{Object type}
52 \value Value The type behaves like a \l{QML Value Types}{Value type}
53 \value None The type is a \l{QML Namespaces}{namespace}, or is invalid
54 \value Sequence The type behaves like a \l{QML Sequence Types}{Sequence type}
55
56 \sa {The QML Type System}
57*/
58
59/*!
60 \enum QQmlSA::BindingType
61 \inmodule QtQmlCompiler
62
63 \brief Describes the type of a \l{QQmlSA::Binding}.
64 \value Invalid There is no binding
65 \value BoolLiteral The binding is a bool literal
66 \value NumberLiteral The binding is a number literal
67 \value StringLiteral The binding is a string literal
68 \value RegExpLiteral The binding is a regular expression literal
69 \value Null The binding is a null literal
70 \value Translation The binding is a \l{Text ID based translations}{translation}
71 \value TranslationById The binding is a \l{Text ID based translations}{translation} by id
72 \value Script The binding is a regular script
73 \value Object The binging is an \l{QML Object Types}{Object}
74 \value Interceptor The binding is an interceptor that can intercept writes to properties such as \l[Quick]{Behavior}
75 \value ValueSource The binging is a \l{Defining QML Types from C++#Property Value Sources}{property value source}
76 \value AttachedProperty The binding is an \l{QML Object Attributes#Attached Properties and Attached Signal Handlers}{attached object}
77 \value GroupProperty The binding is a \l{QML Object Attributes#Grouped Properties}{grouped property}
78*/
79
80/*!
81 \enum QQmlSA::ScriptBindingKind
82 \inmodule QtQmlCompiler
83
84 \brief Describes the script type of a \l{QQmlSA::Binding} of type \l{Script}.
85 \value Invalid The binding has an invalid script
86 \value PropertyBinding The binding is bound to a property
87 \value SignalHandler The binding is a \l{Signal and Handler Event System#Receiving signals with signal handlers}{signal handler}
88 \value ChangeHandler The binding is a \l{Signal and Handler Event System#Property change signal handlers}{change handler}
89*/
90
91/*!
92 \enum QQmlSA::ScopeType
93 \brief Describes the type of QML scope.
94 \value JSFunctionScope The scope is a JavaScript function:
95 \badcode
96 Item {
97 function f() : int { <- begin
98 return 1
99 } <- end
100 }
101 \endcode
102 \value JSLexicalScope The scope is a JavaScript lexical scope:
103 \badcode
104 property int i: { <- begin
105 let a = 1
106 { <- begin
107 console.log("hello")
108 } <- end
109 return a
110 } <- end
111 \endcode
112 \value QMLScope The scope is a QML Object:
113 \badcode
114 Item { <- begin
115 x: 50
116 } <- end
117 \endcode
118 \value GroupedPropertyScope The scope is a \l{QML Object Attributes#Grouped Properties}{grouped property}:
119 \badcode
120 Text {
121 font { <- begin
122 pixelSize: 12
123 bold: true
124 } <- end
125 }
126 \endcode
127 \value AttachedPropertyScope The scope is an \l{QML Object Attributes#Attached Properties and Attached Signal Handlers}{attached property}:
128 \badcode
129 Item {
130 Component.onCompleted: console.log("Hello")
131 ^^^^^^^^^
132 \ Scope of attached property Component
133 }
134 \endcode
135 \value EnumScope The scope is a QML \l{QML Enumerations}{enum}:
136 \badcode
137 enum E { <- begin
138 A,
139 B,
140 C
141 } <- end
142 \endcode
143 \value [since 6.11] BindingFunctionScope The scope represents the expression of a binding:
144 \badcode
145 Item {
146 width: <- begin 10 +
147 2 *parent.width <- end
148 }
149 \endcode
150 Before Qt 6.11, this was reported as a JSFunctionScope
151 \value [since 6.11] SignalHandlerFunctionScope The scope represents a function used as a signal handler:
152 \badcode
153 Timer {
154 onTriggered: <- begin console.log("hi") <- end
155 }
156 \endcode
157 Before Qt 6.11, this was reported as a JSFunctionScope
158
159 Each entry is shown with an example scope of the matching type in QML code.
160*/
161
162/*!
163 \class QQmlSA::Binding::Bindings
164 \inmodule QtQmlCompiler
165
166 \brief Holds multiple property name to property binding associations.
167 */
168
169/*!
170 Constructs a new Bindings object.
171 */
173
174BindingsPrivate::BindingsPrivate(QQmlSA::Binding::Bindings *iface) : q_ptr{ iface } { }
175
176/*!
177 Creates a copy of \a other.
178 */
180 : d_ptr{ new BindingsPrivate{ this, *other.d_func() } }
181{
182}
183
184/*!
185 Destroys the Bindings object.
186 */
187Binding::Bindings::~Bindings() = default;
188
189BindingsPrivate::BindingsPrivate(QQmlSA::Binding::Bindings *iface, const BindingsPrivate &other)
190 : m_bindings{ other.m_bindings.begin(), other.m_bindings.end() }, q_ptr{ iface }
191{
192}
193
194BindingsPrivate::BindingsPrivate(QQmlSA::Binding::Bindings *iface, BindingsPrivate &&other)
195 : m_bindings{ std::move(other.m_bindings) }, q_ptr{ iface }
196{
197}
198
199/*!
200 Returns an iterator to the beginning of the bindings.
201 */
203{
204 Q_D(const Bindings);
205 return d->constBegin();
206}
207
208/*!
209 \fn QMultiHash<QString, Binding>::const_iterator Binding::Bindings::begin() const
210 Same as constBegin().
211 */
212
214{
215 return m_bindings.constBegin();
216}
217
218/*!
219 Returns an iterator to the end of the bindings.
220 */
222{
223 Q_D(const Bindings);
224 return d->constEnd();
225}
226
227/*!
228 \fn QMultiHash<QString, Binding>::const_iterator Binding::Bindings::end() const
229 Same as constEnd().
230 */
231
233{
234 return m_bindings.constEnd();
235}
236
237/*!
238 \class QQmlSA::Binding
239 \inmodule QtQmlCompiler
240
241 \brief Represents a single QML property binding for a specific type.
242 */
243
244/*!
245 Constructs a new Binding object.
246 */
247Binding::Binding() : d_ptr{ new BindingPrivate{ this } } { }
248
249BindingPrivate::BindingPrivate(Binding *iface) : q_ptr{ iface } { }
250
251/*!
252 Creates a copy of \a other.
253*/
254Binding::Binding(const Binding &other) : d_ptr{ new BindingPrivate{ this, *other.d_func() } } { }
255
256/*!
257 Move-constructs a \c Binding instance.
258*/
260 : d_ptr{ new BindingPrivate{ this, *other.d_func() } } { }
261
262
263/*!
264 Assigns \a other to this Binding instance.
265*/
267{
268 if (*this == other)
269 return *this;
270
271 Q_D(Binding);
274 d->q_ptr = this;
276 return *this;
277}
278
279/*!
280 Move-assigns \a other to this Binding instance.
281*/
283{
284 if (*this == other)
285 return *this;
286
287 Q_D(Binding);
290 d->q_ptr = this;
292 return *this;
293}
294
295/*!
296 Destroys the binding.
297*/
298Binding::~Binding() = default;
299
300bool Binding::operatorEqualsImpl(const Binding &lhs, const Binding &rhs)
301{
302 return lhs.d_func()->m_binding == rhs.d_func()->m_binding
305}
306
307BindingPrivate::BindingPrivate(Binding *iface, const BindingPrivate &other)
309 m_isAttached{ other.m_isAttached }
310{
311}
312
313QQmlSA::Binding BindingPrivate::createBinding(const QQmlJSMetaPropertyBinding &binding)
314{
315 QQmlSA::Binding saBinding;
316 saBinding.d_func()->m_binding = binding;
317 return saBinding;
318}
319
320QQmlJSMetaPropertyBinding BindingPrivate::binding(QQmlSA::Binding &binding)
321{
322 return binding.d_func()->m_binding;
323}
324
325const QQmlJSMetaPropertyBinding BindingPrivate::binding(const QQmlSA::Binding &binding)
326{
327 return binding.d_func()->m_binding;
328}
329
330/*!
331 Returns the type of the property of this binding if it is a group property,
332 otherwise returns an invalid Element.
333 */
338
339/*!
340 Returns the Element scope in which the binding is defined.
341 */
343{
344 return BindingPrivate::get(this)->m_bindingScope;
345}
346
347/*!
348 Returns the type of this binding.
349 */
354
355/*!
356 Returns the associated string literal if the content type of this binding is
357 StringLiteral, otherwise returns an empty string.
358 */
360{
361 return BindingPrivate::binding(*this).stringValue();
362}
363
364/*!
365 Returns the name of the property bound with this binding.
366 */
368{
369 return BindingPrivate::binding(*this).propertyName();
370}
371
372/*!
373 Returns \c true if this type is attached to another one, \c false otherwise.
374 */
375bool Binding::isAttached() const
376{
377 return BindingPrivate::get(this)->m_isAttached;
378}
379
380/*!
381 Returns the attached type if the content type of this binding is
382 AttachedProperty, otherwise returns an invalid Element.
383 */
388
389#if QT_DEPRECATED_SINCE(6, 9)
390/*!
391 Returns the attached type if the content type of this binding is
392 AttachedProperty, otherwise returns an invalid Element.
393
394 \deprecated [6.9] Use the better named attachedType() method.
395 */
397{
398 return attachedType();
399}
400#endif
401
402/*!
403 Returns the location in the QML code where this binding is defined.
404 */
410
411/*!
412 Returns the associated number if the content type of this binding is
413 NumberLiteral, otherwise returns 0.
414 */
415double Binding::numberValue() const
416{
417 return BindingPrivate::binding(*this).numberValue();
418}
419
420/*!
421 Returns the kind of the associated script if the content type of this
422 binding is Script, otherwise returns Invalid.
423 */
428
429/*!
430 Returns \c true if this binding has an objects, otherwise returns \c false.
431 */
432bool Binding::hasObject() const
433{
434 return BindingPrivate::binding(*this).hasObject();
435}
436
437/*!
438 Returns the type of the associated object if the content type of this
439 binding is Object, otherwise returns an invalid Element.
440 */
445
446/*!
447 Returns whether this binding has script value type undefined like when it
448 is assigned \c undefined. If the content type of this binding is not
449 \l{QQmlSA::BindingType::Script}, returns \c false.
450 */
457
458/*!
459 Returns whether this binding has script value type function like when it
460 is assigned a (lambda) method, an arrow function or a statement block. If
461 the content type of this binding is not \l{QQmlSA::BindingType::Script},
462 returns \c false.
463 */
470
471/*!
472 Returns \c true if \a bindingType is a literal type, and \c false
473 otherwise.
474 */
479
480/*!
481 \fn friend bool Binding::operator==(const Binding &lhs, const Binding &rhs)
482 Returns \c true if \a lhs and \a rhs are equal, and \c false otherwise. Two
483 \c Bindings are considered equal if their property name, content type, and
484 source location match.
485 */
486/*!
487 \fn friend bool Binding::operator!=(const Binding &lhs, const Binding &rhs)
488 Returns \c true if \a lhs and \a rhs are not equal, and \c false otherwise.
489 Two \c Bindings are considered equal if their property name, content type,
490 and source location match.
491 */
492
493/*!
494 Constructs a new Methods object.
495*/
497
498/*!
499 Creates a copy of \a other.
500 */
502 : d_ptr{ new MethodsPrivate{ this, *other.d_func() } }
503{
504}
505
506/*!
507 Destroys the Methods instance.
508 */
509QQmlSA::Method::Methods::~Methods() = default;
510
511/*!
512 Returns an iterator to the beginning of the methods.
513 */
515{
516 Q_D(const Methods);
517 return d->constBegin();
518}
519
520/*!
521 \fn QMultiHash<QString, QQmlSA::Method>::const_iterator QQmlSA::Method::Methods::begin() const
522 Returns an iterator to the beginning of the methods.
523 */
524
526{
527 return m_methods.constBegin();
528}
529
530/*!
531 Returns an iterator to the end of the methods.
532 */
534{
535 Q_D(const Methods);
536 return d->constEnd();
537}
538
539/*!
540 \fn QMultiHash<QString, QQmlSA::Method>::const_iterator QQmlSA::Method::Methods::end() const
541 Returns an iterator to the end of the methods.
542 */
543
545{
546 return m_methods.constEnd();
547}
548
549MethodsPrivate::MethodsPrivate(QQmlSA::Method::Methods *iface) : q_ptr{ iface } { }
550
551MethodsPrivate::MethodsPrivate(QQmlSA::Method::Methods *iface, const MethodsPrivate &other)
553{
554}
555
556MethodsPrivate::MethodsPrivate(QQmlSA::Method::Methods *iface, MethodsPrivate &&other)
558{
559}
560
561MethodPrivate::MethodPrivate(Method *iface) : q_ptr{ iface } { }
562
563MethodPrivate::MethodPrivate(Method *iface, const MethodPrivate &other)
565{
566}
567
569{
570 return m_method.methodName();
571}
572
573QQmlSA::SourceLocation MethodPrivate::sourceLocation() const
574{
575 return QQmlSA::SourceLocationPrivate::createQQmlSASourceLocation(m_method.sourceLocation());
576}
577
579{
580 return m_method.methodType();
581}
582
583/*!
584 \class QQmlSA::Method
585 \inmodule QtQmlCompiler
586
587 \brief Represents a QML method.
588 */
589
590/*!
591 Constructs a new Method object.
592 */
593Method::Method() : d_ptr{ new MethodPrivate{ this } } { }
594
595/*!
596 Creates a copy of \a other.
597 */
598Method::Method(const Method &other) : d_ptr{ new MethodPrivate{ this, *other.d_func() } } { }
599
600/*!
601 Move-constructs a Method instance.
602 */
604 : d_ptr{ new MethodPrivate{ this, std::move(*other.d_func()) } }
605{
606}
607
608/*!
609 Assigns \a other to this Method instance.
610 */
612{
613 if (*this == other)
614 return *this;
615
617 d_func()->q_ptr = this;
618 return *this;
619}
620
621/*!
622 Move-assigns \a other to this Method instance.
623 */
625{
626 if (*this == other)
627 return *this;
628
630 d_func()->q_ptr = this;
631 return *this;
632}
633
634/*!
635 Destroys the Method.
636 */
637Method::~Method() = default;
638
639/*!
640 Returns the name of the this method.
641 */
643{
644 Q_D(const Method);
645 return d->methodName();
646}
647
648/*!
649 Returns the type of this method.
650 */
652{
653 Q_D(const Method);
654 return d->methodType();
655}
656
657/*!
658 \fn friend bool Method::operator==(const Method &lhs, const Method &rhs)
659 Returns \c true if \a lhs and \a rhs are equal, and \c false otherwise.
660 */
661/*!
662 \fn friend bool Method::operator!=(const Method &lhs, const Method &rhs)
663 Returns \c true if \a lhs and \a rhs are not equal, and \c false otherwise.
664 */
665
666/*!
667 Returns the location in the QML code where this method is defined.
668 */
670{
671 Q_D(const Method);
672 return d->sourceLocation();
673}
674
675bool Method::operatorEqualsImpl(const Method &lhs, const Method &rhs)
676{
677 return lhs.d_func()->m_method == rhs.d_func()->m_method;
678}
679
680QQmlSA::Method MethodPrivate::createMethod(const QQmlJSMetaMethod &jsMethod)
681{
682 QQmlSA::Method saMethod;
683 auto &wrappedMethod = saMethod.d_func()->m_method;
684 wrappedMethod = jsMethod;
685 return saMethod;
686}
687
688QQmlSA::Method::Methods
689MethodsPrivate::createMethods(const QMultiHash<QString, QQmlJSMetaMethod> &hash)
690{
691 QMultiHash<QString, QQmlSA::Method> saMethods;
692 for (const auto &[key, value] : hash.asKeyValueRange()) {
693 saMethods.insert(key, MethodPrivate::createMethod(value));
694 }
695
696 QQmlSA::Method::Methods methods;
697 methods.d_func()->m_methods = std::move(saMethods);
698 return methods;
699}
700
701QQmlJSMetaMethod MethodPrivate::method(const QQmlSA::Method &method)
702{
703 return method.d_func()->m_method;
704}
705
706/*!
707 \class QQmlSA::PropertyPrivate
708 \inmodule QtQmlCompiler
709 \internal
710*/
711PropertyPrivate::PropertyPrivate(Property *iface) : q_ptr{ iface } { }
712
713PropertyPrivate::PropertyPrivate(Property *iface, const PropertyPrivate &other)
715{
716}
717
720{
721}
722
724{
725 return m_property.typeName();
726}
727
729{
730 return m_property.isValid();
731}
732
733/*!
734 Returns whether this property is readonly. Properties defined in QML are readonly when their
735 definition has the 'readonly' keyword. Properties defined in C++ are readonly when they do not
736 have a WRITE accessor function.
737 */
739{
740 return !m_property.isWritable();
741}
742
743/*!
744 Returns the type that this property was defined with.
745 */
746QQmlSA::Element PropertyPrivate::type() const
747{
748 return QQmlJSScope::createQQmlSAElement(m_property.type());
749}
750
751QQmlJSMetaProperty PropertyPrivate::property(const QQmlSA::Property &property)
752{
753 return property.d_func()->m_property;
754}
755
756QQmlSA::Property PropertyPrivate::createProperty(const QQmlJSMetaProperty &property)
757{
758 QQmlSA::Property saProperty;
759 auto &wrappedProperty = saProperty.d_func()->m_property;
760 wrappedProperty = property;
761 return saProperty;
762}
763
764/*!
765 \class QQmlSA::Property
766 \inmodule QtQmlCompiler
767
768 \brief Represents a QML property.
769 */
770
771/*!
772 Constructs a new Property object.
773 */
774Property::Property() : d_ptr{ new PropertyPrivate{ this } } { }
775
776/*!
777 Creates a copy of \a other.
778 */
780 : d_ptr{ new PropertyPrivate{ this, *other.d_func() } } { }
781
782/*!
783 Move-constructs a Property instance.
784 */
786 : d_ptr{ new PropertyPrivate{ this, std::move(*other.d_func()) } }
787{
788}
789
790/*!
791 Assigns \a other to this Property instance.
792 */
794{
795 if (*this == other)
796 return *this;
797
799 d_func()->q_ptr = this;
800 return *this;
801}
802
803/*!
804 Move-assigns \a other to this Property instance.
805 */
807{
808 if (*this == other)
809 return *this;
810
812 d_func()->q_ptr = this;
813 return *this;
814}
815
816/*!
817 Destroys this property.
818 */
819Property::~Property() = default;
820
821/*!
822 Returns the name of the type of this property.
823 */
825{
826 Q_D(const Property);
827 return d->typeName();
828}
829
830/*!
831 Returns \c true if this property is valid, \c false otherwise.
832 */
833bool Property::isValid() const
834{
835 Q_D(const Property);
836 return d->isValid();
837}
838
839/*!
840 Returns \c true if this property is read-only, \c false otherwise.
841 */
842bool Property::isReadonly() const
843{
844 Q_D(const Property);
845 return d->isReadonly();
846}
847
848/*!
849 Returns the type of this property.
850*/
852{
853 Q_D(const Property);
854 return d->type();
855}
856
857/*!
858 \fn friend bool Property::operator==(const Property &lhs, const Property &rhs)
859 Returns \c true if \a lhs and \a rhs are equal, and \c false otherwise.
860 */
861/*!
862 \fn friend bool Property::operator!=(const Property &lhs, const Property &rhs)
863 Returns \c true if \a lhs and \a rhs are not equal, and \c false otherwise.
864 */
865
866
868{
869 return lhs.d_func()->m_property == rhs.d_func()->m_property;
870}
871
872/*!
873 \class QQmlSA::Element
874 \inmodule QtQmlCompiler
875
876 \brief Represents a QML type.
877 */
878
879/*!
880 Constructs a new Element object.
881 */
883{
884 new (m_data) QQmlJSScope::ConstPtr();
885}
886
887/*!
888 Creates a copy of \a other.
889 */
894
895/*!
896 \fn Element::Element(Element &&other) noexcept
897 Move-constructs an Element instance.
898 */
899
900/*!
901 Assigns \a other to this element instance.
902 */
904{
905 if (this == &other)
906 return *this;
907
908 *reinterpret_cast<QQmlJSScope::ConstPtr *>(m_data) = QQmlJSScope::scope(other);
909 return *this;
910}
911
912/*!
913 \fn QQmlSA::Element &QQmlSA::Element::operator=(QQmlSA::Element &&other)
914 Move-assigns \a other to this Element instance.
915 */
916
917/*!
918 Destroys the element.
919 */
921{
922 (*reinterpret_cast<QQmlJSScope::ConstPtr *>(m_data)).QQmlJSScope::ConstPtr::~ConstPtr();
923}
924
925/*!
926 Returns the type of Element's scope.
927 */
929{
930 return QQmlJSScope::scope(*this)->scopeType();
931}
932
933/*!
934 Returns the Element this Element derives from.
935 */
940
941/*!
942 Returns the name of the Element this Element derives from.
943 */
948
949/*!
950 Returns the Element that encloses this Element.
951 */
956
957/*!
958 Returns whether this Element inherits from \a element.
959 */
960bool Element::inherits(const Element &element) const
961{
963}
964
965/*!
966 Returns whether this Element is the root component of its QML file.
967 */
969{
970 return QQmlJSScope::scope(*this)->isFileRootComponent();
971}
972
973/*!
974 Returns \c true if this element is null, \c false otherwise.
975 */
976bool Element::isNull() const
977{
978 return QQmlJSScope::scope(*this).isNull();
979}
980
981/*!
982 \internal
983 */
985{
986 return QQmlJSScope::scope(*this)->internalName();
987}
988
989/*!
990 Returns the access semantics of this Element. For example, Reference,
991 Value or Sequence.
992 */
994{
995 return QQmlJSScope::scope(*this)->accessSemantics();
996}
997
998/*!
999 Returns \c true for objects defined from Qml, and \c false for objects declared from C++.
1000 */
1002{
1003 return QQmlJSScope::scope(*this)->isComposite();
1004}
1005
1006/*!
1007 Returns whether this Element has a property with the name \a propertyName.
1008 */
1010{
1011 return QQmlJSScope::scope(*this)->hasProperty(propertyName);
1012}
1013
1014/*!
1015 Returns whether this Element defines a property with the name \a propertyName
1016 which is not defined on its base or extension objects.
1017 */
1019{
1021}
1022
1023/*!
1024 Returns the property with the name \a propertyName if it is found in this
1025 Element or its base and extension objects, otherwise returns an invalid property.
1026 */
1031
1032/*!
1033 Returns whether the property with the name \a propertyName resolved on this
1034 Element is required. Returns false if the the property couldn't be found.
1035 */
1040
1041/*!
1042 Returns the name of the default property of this Element. If it doesn't
1043 have one, returns an empty string.
1044 */
1046{
1047 return QQmlJSScope::scope(*this)->defaultPropertyName();
1048}
1049
1050/*!
1051 Returns whether this Element has a method with the name \a methodName.
1052 */
1054{
1055 return QQmlJSScope::scope(*this)->hasMethod(methodName);
1056}
1057
1058/*!
1059 \class QQmlSA::Method::Methods
1060 \inmodule QtQmlCompiler
1061
1062 \brief Holds multiple method name to method associations.
1063 */
1064
1065/*!
1066 Returns this Elements's methods, which are not defined on its base or
1067 extension objects.
1068 */
1073
1074/*!
1075 Returns the location in the QML code where this Element is defined.
1076 */
1082
1083/*!
1084 Returns the location in the QML code where this Element is assigned its id, if it has one.
1085 */
1091
1092/*!
1093 Returns the file path of the QML code that defines this Element.
1094 */
1096{
1097 return QQmlJSScope::scope(*this)->filePath();
1098}
1099
1100/*!
1101 Returns whether this Element has a property binding with the name \a name.
1102 */
1104{
1105 return QQmlJSScope::scope(*this)->hasPropertyBindings(name);
1106}
1107
1108/*!
1109 Returns whether this Element has property bindings which are not defined in
1110 its base or extension objects and that have name \a propertyName.
1111 */
1116
1117/*!
1118 Returns this Element's property bindings which are not defined on its base
1119 or extension objects.
1120 */
1125
1126/*!
1127 Returns this Element's property bindings which are not defined on its base
1128 or extension objects and that have the name \a propertyName.
1129 */
1135
1136/*!
1137 Returns this Element's property bindings that have the name \a propertyName.
1138 */
1140{
1141 const auto &bindings = QQmlJSScope::scope(*this)->propertyBindings(propertyName);
1142
1144 for (const auto &jsBinding : bindings) {
1146 }
1147 return saBindings;
1148}
1149
1150QQmlSA::Binding::Bindings
1151BindingsPrivate::createBindings(const QMultiHash<QString, QQmlJSMetaPropertyBinding> &hash)
1152{
1153 QMultiHash<QString, QQmlSA::Binding> saBindings;
1154 for (const auto &[key, value] : hash.asKeyValueRange()) {
1155 saBindings.insert(key, BindingPrivate::createBinding(value));
1156 }
1157
1158 QQmlSA::Binding::Bindings bindings;
1159 bindings.d_func()->m_bindings = std::move(saBindings);
1160 return bindings;
1161}
1162
1176
1177/*!
1178 Returns \c true if this element is not null, \c false otherwise.
1179 */
1180Element::operator bool() const
1181{
1182 return bool(QQmlJSScope::scope(*this));
1183}
1184
1185/*!
1186 Returns \c true if this element is null, \c false otherwise.
1187 */
1188bool Element::operator!() const
1189{
1190 return !QQmlJSScope::scope(*this);
1191}
1192
1193/*!
1194 Returns the name of this Element.
1195 */
1197{
1198 if (isNull())
1199 return {};
1201}
1202
1203/*!
1204 \fn friend inline bool Element::operator==(const Element &lhs, const Element &rhs)
1205 Returns \c true if \a lhs and \a rhs are equal, and \c false otherwise.
1206 */
1207/*!
1208 \fn friend inline bool Element::operator!=(const Element &lhs, const Element &rhs)
1209 Returns \c true if \a lhs and \a rhs are not equal, and \c false otherwise.
1210 */
1211
1212bool Element::operatorEqualsImpl(const Element &lhs, const Element &rhs)
1213{
1214 return QQmlJSScope::scope(lhs) == QQmlJSScope::scope(rhs);
1215}
1216
1217/*!
1218 \fn friend inline qsizetype Element::qHash(const Element &key, qsizetype seed) noexcept
1219 Returns the hash for \a key using \a seed to seed the calculation.
1220*/
1221
1223{
1224 return qHash(QQmlJSScope::scope(key), seed);
1225}
1226
1227/*!
1228 \class QQmlSA::GenericPass
1229 \inmodule QtQmlCompiler
1230
1231 \brief The base class for static analysis passes.
1232
1233 This class contains common functionality used by more specific passses.
1234 Custom passes should not directly derive from it, but rather from one of
1235 its subclasses.
1236 \sa ElementPass, PropertyPass
1237 */
1238
1240 Q_DECLARE_PUBLIC(GenericPass);
1241
1242public:
1243 GenericPassPrivate(GenericPass *iface, PassManager *manager)
1244 : m_manager{ manager }, q_ptr{ iface }
1245 {
1246 Q_ASSERT(manager);
1247 }
1248
1249private:
1250 PassManager *m_manager = nullptr;
1251
1252 GenericPass *q_ptr = nullptr;
1253};
1254
1255/*!
1256 Creates a generic pass.
1257 */
1260
1261/*!
1262 Destroys the GenericPass instance.
1263 */
1264GenericPass::~GenericPass() = default;
1265
1266/*!
1267 Emits a warning message \a diagnostic about an issue of type \a id.
1268 */
1273
1274/*!
1275 Emits warning message \a diagnostic about an issue of type \a id located at
1276 \a srcLocation.
1277 */
1287
1288/*!
1289 Emits a warning message \a diagnostic about an issue of type \a id located at
1290 \a srcLocation and with suggested fix \a fix.
1291 */
1302
1303/*!
1304 Returns the type corresponding to \a typeName inside the
1305 currently analysed file.
1306 */
1314
1315/*!
1316 Returns the attached type corresponding to \a typeName used inside
1317 the currently analysed file.
1318 */
1329
1330/*!
1331 Returns the type of \a typeName defined in module \a moduleName.
1332 If an attached type and a non-attached type share the same name
1333 (for example, \c ListView), the \l Element corresponding to the
1334 non-attached type is returned.
1335 To obtain the attached type, use \l resolveAttached.
1336 */
1345
1346/*!
1347 Returns the type of the built-in type identified by \a typeName.
1348 Built-in types encompass \c{C++} types which the QML engine can handle
1349 without any imports (e.g. \l QDateTime and \l QString), global EcmaScript
1350 objects like \c Number, as well as the \l {QML Global Object}
1351 {global Qt object}.
1352 */
1354{
1355 Q_D(const GenericPass);
1358 // we have to check both cpp names
1360 if (!scope) {
1361 // and qml names (e.g. for bool) - builtinImportHelper is private, so we can't do it in one call
1364 }
1366}
1367
1368/*!
1369 Returns the attached type of \a typeName defined in module \a moduleName.
1370 */
1376
1377/*!
1378 Returns the element representing the type of literal in \a binding. If the
1379 binding does not contain a literal value, a null Element is returned.
1380 */
1388
1389/*!
1390 Returns the element in \a context that has id \a id.
1391 */
1400
1401/*!
1402 Returns the id of \a element in a given \a context.
1403 */
1412
1413/*!
1414 Returns the source code located within \a location.
1415 */
1424
1425/*!
1426 \class QQmlSA::PassManager
1427 \inmodule QtQmlCompiler
1428
1429 \brief Can analyze an element and its children with static analysis passes.
1430 */
1431
1432// explicitly defaulted out-of-line for PIMPL
1433PassManager::PassManager() = default;
1434PassManager::~PassManager() = default;
1435
1436/*!
1437 Registers a static analysis \a pass to be run on all elements.
1438 */
1444
1445/*!
1446 \internal
1447 \brief PassManager::registerElementPass registers ElementPass
1448 with the pass manager.
1449 \param pass The registered pass. Ownership is transferred to the pass manager.
1450 */
1455
1457static QString lookupName(const QQmlSA::Element &element, LookupMode mode = Lookup)
1458{
1459 QString name;
1460 if (element.isNull() || QQmlJSScope::scope(element)->internalName().isEmpty()) {
1461 // Bail out with an invalid name, this type is so screwed up we can't do anything reasonable
1462 // with it We should have warned about it in another plac
1463 if (element.isNull() || element.baseType().isNull())
1464 return u"$INVALID$"_s;
1465 name = QQmlJSScope::scope(element.baseType())->internalName();
1466 } else {
1467 name = QQmlJSScope::scope(element)->internalName();
1468 }
1469
1470 const QString filePath =
1471 (mode == Register || !element.baseType() ? element : element.baseType()).filePath();
1472
1473 if (QQmlJSScope::scope(element)->isComposite() && !filePath.endsWith(u".h"))
1474 name += u'@' + filePath;
1475 return name;
1476}
1477
1478/*!
1479 Registers a static analysis pass for properties. The \a pass will be run on
1480 every property matching the \a moduleName, \a typeName and \a propertyName.
1481
1482 Omitting the \a propertyName will register this pass for all properties
1483 matching the \a typeName and \a moduleName.
1484
1485 Setting \a allowInheritance to \c true means that the filtering on the type
1486 also accepts types deriving from \a typeName.
1487
1488 \a pass is passed as a \c{std::shared_ptr} to allow reusing the same pass
1489 on multiple elements:
1490 \code
1491 auto titleValiadorPass = std::make_shared<TitleValidatorPass>(manager);
1492 manager->registerPropertyPass(titleValidatorPass,
1493 "QtQuick", "Window", "title");
1494 manager->registerPropertyPass(titleValidatorPass,
1495 "QtQuick.Controls", "Dialog", "title");
1496 \endcode
1497
1498 \note Running analysis passes on too many items can be expensive. This is
1499 why it is generally good to filter down the set of properties of a pass
1500 using the \a moduleName, \a typeName and \a propertyName.
1501
1502 Returns \c true if the pass was successfully added, \c false otherwise.
1503 Adding a pass fails when the \l{QQmlSA::Element}{Element} specified by
1504 \a moduleName and \a typeName does not exist.
1505
1506 \sa PropertyPass
1507*/
1515
1519{
1520 if (moduleName.isEmpty() != typeName.isEmpty()) {
1521 qWarning() << "Both the moduleName and the typeName must be specified "
1522 "for the pass to be registered for a specific element.";
1523 }
1524
1525 QString name;
1526 if (!moduleName.isEmpty() && !typeName.isEmpty()) {
1530
1531 if (element.isNull())
1532 return false;
1533
1535 }
1539
1540 return true;
1541}
1542
1563
1565 const QString prefix, bool isAttached)
1566{
1569 for (auto &binding : ownBindings) {
1570 switch (binding.bindingType()) {
1573 prefix + binding.propertyName() + u'.');
1574 continue; // don't insert into m_bindingsByLocation
1577 prefix + binding.propertyName() + u'.', true);
1578 continue; // don't insert into m_bindingsByLocation
1581 u"qsTr"_s, element, binding.sourceLocation());
1582 break;
1583 }
1586 u"qsTrId"_s, element, binding.sourceLocation());
1587 break;
1588 }
1589 default:
1590 break;
1591 }
1592
1599 }
1600}
1601
1602/*!
1603 Runs the element passes over \a root and all its children.
1604 */
1606{
1608 d->analyze(root);
1609}
1610
1611static QQmlJS::ChildScopesIterator childScopesBegin(const Element &element)
1612{
1613 return QQmlJSScope::scope(element)->childScopesBegin();
1614}
1615
1616static QQmlJS::ChildScopesIterator childScopesEnd(const Element &element)
1617{
1618 return QQmlJSScope::scope(element)->childScopesEnd();
1619}
1620
1622{
1625 while (!runStack.isEmpty()) {
1626 auto element = runStack.takeLast();
1628 for (auto &elementPass : m_elementPasses)
1631
1632 for (auto it = childScopesBegin(element), end = childScopesEnd(element); it != end; ++it) {
1633 if ((*it)->scopeType() == QQmlSA::ScopeType::QMLScope)
1635 }
1636 }
1637}
1638
1647
1655
1663
1666{
1667 const auto it = m_bindingsByLocation.find(location.offset());
1668
1669 // If there's no matching binding that means we're in a nested Ret somewhere inside an
1670 // expression
1671 if (it == m_bindingsByLocation.cend())
1672 return;
1673
1674 const auto &[offset, binding] = *it;
1677
1681
1683 return;
1684
1689 }
1690}
1691
1692/*!
1693 Returns \c true if the module named \a module has been imported by the
1694 QML to be analyzed, \c false otherwise.
1695
1696 This can be used to skip registering a pass which is specific to a specific
1697 module.
1698
1699 \code
1700 if (passManager->hasImportedModule("QtPositioning"))
1701 passManager->registerElementPass(
1702 std::make_unique<PositioningPass>(passManager)
1703 );
1704 \endcode
1705
1706 \sa registerPropertyPass(), registerElementPass()
1707 */
1709{
1710 return PassManagerPrivate::visitor(*this)->imports().hasType(u"$module$." + module.toString());
1711}
1712
1713/*!
1714 Returns \c true if warnings of \a category are enabled, \c false otherwise.
1715 */
1720
1725
1730
1732 const QString &propertyName)
1733{
1735
1736 for (auto it = QQmlJSScope::scope(element); it; it = it->baseType())
1738
1740
1741 for (const QString &typeName : typeNames) {
1742 for (auto &pass :
1744 if (pass.first == pass.second)
1745 continue;
1746
1747 for (auto it = pass.first; it != pass.second; it++) {
1749 continue;
1752 }
1753 }
1754 }
1755 return passes;
1756}
1757
1759 emitWarning(u"Type: " + element.baseTypeName(), qmlPlugin);
1760 if (auto bindings = element.propertyBindings(u"objectName"_s); !bindings.isEmpty()) {
1761 emitWarning(u"is named: " + bindings.first().stringValue(), qmlPlugin);
1762 }
1765 + u" elements to property "_s + defPropName,
1766 qmlPlugin);
1767 }
1768}
1769
1770/*!
1771 \class QQmlSA::LintPlugin
1772 \inmodule QtQmlCompiler
1773
1774 \brief Base class for all static analysis plugins.
1775 */
1776
1777/*!
1778 \fn LintPlugin::LintPlugin()
1779 Constructs a LintPlugin object.
1780 */
1781
1782/*!
1783 \fn virtual LintPlugin::~LintPlugin()
1784 Destroys the LintPlugin instance.
1785 */
1786
1787/*!
1788 \fn void QQmlSA::LintPlugin::registerPasses(PassManager *manager, const Element &rootElement)
1789
1790 Adds a pass \a manager that will be executed on \a rootElement.
1791 */
1792
1793/*!
1794 \class QQmlSA::ElementPass
1795 \inmodule QtQmlCompiler
1796
1797 \brief Base class for all static analysis passes on elements.
1798
1799 ElementPass is the simpler of the two analysis passes. It will consider every element in
1800 a file. The \l shouldRun() method can be used to filter out irrelevant elements, and the
1801 \l run() method is doing the initial work.
1802
1803 Common tasks suitable for an ElementPass are
1804 \list
1805 \li checking that properties of an Element are not combined in a nonsensical way
1806 \li validating property values (e.g. that a property takes only certain enum values)
1807 \li checking behavior dependent on an Element's parent (e.g. not using \l {Item::width}
1808 when the parent element is a \c Layout).
1809 \endlist
1810
1811 As shown in the snippet below, it is recommended to do necessary type resolution in the
1812 constructor of the ElementPass and cache it in local members, and to implement some
1813 filtering via \l shouldRun() to keep the static analysis performant.
1814
1815 \code
1816 using namespace QQmlSA;
1817 class MyElementPass : public ElementPass
1818 {
1819 Element myType;
1820 public:
1821 MyElementPass(QQmlSA::PassManager *manager)
1822 : myType(resolveType("MyModule", "MyType")) {}
1823
1824 bool shouldRun(const Element &element) override
1825 {
1826 return element.inherits(myType);
1827 }
1828 void run(const Element &element) override
1829 {
1830 // actual pass logic
1831 }
1832 }
1833 \endcode
1834
1835 ElementPasses have limited insight into how an element's properties are used. If you need
1836 that information, consider using a \l PropertyPass instead.
1837
1838 \note ElementPass will only ever consider instantiable types. Therefore, it is unsuitable
1839 to analyze attached types and singletons. Those need to be handled via a PropertyPass.
1840 */
1841
1842/*!
1843 \fn ElementPass::ElementPass(PassManager *manager)
1844 Creates an ElementPass object and uses \a manager to refer to the pass manager.
1845*/
1846
1847/*!
1848 \fn void QQmlSA::ElementPass::run(const Element &element)
1849
1850 Executes if \c shouldRun() returns \c true. Performs the real computation
1851 of the pass on \a element.
1852 This method is meant to be overridden. Calling the base method is not
1853 necessary.
1854 */
1855
1856/*!
1857 Controls whether the \c run() function should be executed on the given \a element.
1858 Subclasses can override this method to improve performance of the analysis by
1859 filtering out elements which are not relevant.
1860
1861 The default implementation unconditionally returns \c true.
1862 */
1864{
1865 (void)element;
1866 return true;
1867}
1868
1869/*!
1870 \class QQmlSA::PropertyPass
1871 \inmodule QtQmlCompiler
1872
1873 \brief Base class for all static analysis passes on properties.
1874 */
1875
1876
1877/*!
1878 Creates a PropertyPass object and uses \a manager to refer to the pass manager.
1879 */
1881
1882/*!
1883 Executes whenever a property gets bound to a value.
1884
1885 The property \a propertyName of \a element is bound to the \a value within
1886 \a bindingScope with \a binding.
1887 */
1898
1899/*!
1900 Executes whenever a property is read.
1901
1902 The property \a propertyName of \a element is read by an instruction within
1903 \a readScope defined at \a location.
1904
1905 This is also executed if the property \a propertyName is called as a function as that requires
1906 the property to be read first.
1907 */
1916
1917/*!
1918 Executes whenever a property or method is called.
1919
1920 The property or method \a propertyName of \a element is called as a function by an instruction
1921 within \a readScope defined at \a location.
1922
1923 \note Currently only direct calls of methods or properties are supported, indirect calls, for
1924 example by storing a method into a JavaScript variable and then calling the variable, are not
1925 recognized.
1926 */
1935
1936/*!
1937 Executes whenever a property is written to.
1938
1939 The property \a propertyName of \a element is written to by an instruction
1940 within \a writeScope defined at \a location. The type of the expression
1941 written to \a propertyName is \a expressionType.
1942 */
1953
1957
1970
1972 const QQmlSA::Binding &binding,
1973 const QQmlSA::Element &bindingScope, const QQmlSA::Element &value)
1974{
1976 emitWarning(u"onBinding element: '"_s
1980 + u"' property: '"_s + propertyName + u"' value: '"_s
1981 + (value.isNull() ? u"NULL"_s
1985 + u"' binding_scope: '"_s
1989 + u"' "_s + QString::number(location.startLine()) + u':'
1992}
1993
2005
2006/*!
2007 Returns bindings by their source location.
2008 */
2014
2015FixSuggestionPrivate::FixSuggestionPrivate(FixSuggestion *iface) : q_ptr{ iface } { }
2016
2017FixSuggestionPrivate::FixSuggestionPrivate(FixSuggestion *iface, const QString &fixDescription,
2018 const QQmlSA::SourceLocation &location,
2019 const QString &replacement)
2020 : m_fixSuggestion{ fixDescription, QQmlSA::SourceLocationPrivate::sourceLocation(location),
2021 replacement },
2022 q_ptr{ iface }
2023{
2024}
2025
2027 const FixSuggestionPrivate &other)
2028 : m_fixSuggestion{ other.m_fixSuggestion }, q_ptr{ iface }
2029{
2030}
2031
2033 : m_fixSuggestion{ std::move(other.m_fixSuggestion) }, q_ptr{ iface }
2034{
2035}
2036
2038{
2039 return m_fixSuggestion.fixDescription();
2040}
2041
2042QQmlSA::SourceLocation FixSuggestionPrivate::location() const
2043{
2044 return QQmlSA::SourceLocationPrivate::createQQmlSASourceLocation(m_fixSuggestion.location());
2045}
2046
2048{
2049 return m_fixSuggestion.replacement();
2050}
2051
2052void FixSuggestionPrivate::setFileName(const QString &fileName)
2053{
2054 m_fixSuggestion.setFilename(fileName);
2055}
2056
2058{
2059 return m_fixSuggestion.filename();
2060}
2061
2062void FixSuggestionPrivate::setHint(const QString &hint)
2063{
2064 m_fixSuggestion.setHint(hint);
2065}
2066
2068{
2069 return m_fixSuggestion.hint();
2070}
2071
2072void FixSuggestionPrivate::setAutoApplicable(bool autoApplicable)
2073{
2074 m_fixSuggestion.setAutoApplicable(autoApplicable);
2075}
2076
2078{
2079 return m_fixSuggestion.isAutoApplicable();
2080}
2081
2082QQmlJSFixSuggestion &FixSuggestionPrivate::fixSuggestion(FixSuggestion &saFixSuggestion)
2083{
2085}
2086
2087const QQmlJSFixSuggestion &FixSuggestionPrivate::fixSuggestion(const FixSuggestion &saFixSuggestion)
2088{
2089 return saFixSuggestion.d_func()->m_fixSuggestion;
2090}
2091
2092/*!
2093 \class QQmlSA::FixSuggestion
2094 \inmodule QtQmlCompiler
2095
2096 \brief Represents a suggested fix for an issue in the source code.
2097 */
2098
2099
2100/*!
2101 Creates a FixSuggestion object.
2102 */
2108
2109/*!
2110 Creates a copy of \a other.
2111 */
2116
2117/*!
2118 Move-constructs a FixSuggestion instance.
2119 */
2121 : d_ptr{ new FixSuggestionPrivate{ this, std::move(*other.d_func()) } }
2122{
2123}
2124
2125/*!
2126 Assigns \a other to this FixSuggestion instance.
2127 */
2129{
2130 if (*this == other)
2131 return *this;
2132
2134 return *this;
2135}
2136
2137/*!
2138 Move-assigns \a other to this FixSuggestion instance.
2139 */
2141{
2142 if (*this == other)
2143 return *this;
2144
2146 return *this;
2147}
2148
2149/*!
2150 Destorys the FixSuggestion instance.
2151 */
2152FixSuggestion::~FixSuggestion() = default;
2153
2154/*!
2155 Returns the description of the fix.
2156 */
2161
2162/*!
2163 Returns the location where the fix would be applied.
2164 */
2170
2171/*!
2172 Returns the fix that will replace the problematic source code.
2173 */
2178
2179/*!
2180 Sets \a fileName as the name of the file where this fix suggestion applies.
2181 */
2186
2187/*!
2188 Returns the name of the file where this fix suggestion applies.
2189 */
2191{
2193}
2194
2195/*!
2196 Sets \a hint as the hint for this fix suggestion.
2197 */
2202
2203/*!
2204 Returns the hint for this fix suggestion.
2205 */
2207{
2208 return FixSuggestionPrivate::fixSuggestion(*this).hint();
2209}
2210
2211/*!
2212 Sets \a autoApplicable to determine whether this suggested fix can be
2213 applied automatically.
2214 */
2219
2220/*!
2221 Returns whether this suggested fix can be applied automatically.
2222 */
2227
2228/*!
2229 \fn friend bool FixSuggestion::operator==(const FixSuggestion &lhs, const FixSuggestion &rhs)
2230 Returns \c true if \a lhs and \a rhs are equal, and \c false otherwise.
2231 */
2232/*!
2233 \fn friend bool FixSuggestion::operator!=(const FixSuggestion &lhs, const FixSuggestion &rhs)
2234 Returns \c true if \a lhs and \a rhs are not equal, and \c false otherwise.
2235 */
2236
2238{
2240}
2241
2257
2259{
2260 return type >= BindingType::BoolLiteral && type <= BindingType::Object;
2261}
2262
2263} // namespace QQmlSA
2264
2265QT_END_NAMESPACE
BindingPrivate(Binding *, const BindingPrivate &)
Definition qqmlsa.cpp:307
\inmodule QtQmlCompiler
Definition qqmlsa.h:52
QMultiHash< QString, Binding >::const_iterator constBegin() const
Definition qqmlsa.cpp:213
QMultiHash< QString, Binding >::const_iterator constEnd() const
Definition qqmlsa.cpp:232
QQmlSA::SourceLocation location() const
Definition qqmlsa.cpp:2042
void setHint(const QString &)
Definition qqmlsa.cpp:2062
void setFileName(const QString &)
Definition qqmlsa.cpp:2052
QString fixDescription() const
Definition qqmlsa.cpp:2037
FixSuggestionPrivate(FixSuggestion *)
Definition qqmlsa.cpp:2015
void setAutoApplicable(bool autoApplicable=true)
Definition qqmlsa.cpp:2072
FixSuggestionPrivate(FixSuggestion *, FixSuggestionPrivate &&)
Definition qqmlsa.cpp:2032
QString replacement() const
Definition qqmlsa.cpp:2047
FixSuggestionPrivate(FixSuggestion *, const FixSuggestionPrivate &)
Definition qqmlsa.cpp:2026
GenericPassPrivate(GenericPass *iface, PassManager *manager)
Definition qqmlsa.cpp:1243
MethodPrivate(Method *, const MethodPrivate &)
Definition qqmlsa.cpp:563
QQmlSA::SourceLocation sourceLocation() const
Definition qqmlsa.cpp:573
MethodType methodType() const
Definition qqmlsa.cpp:578
QString methodName() const
Definition qqmlsa.cpp:568
MethodsPrivate(QQmlSA::Method::Methods *, MethodsPrivate &&)
Definition qqmlsa.cpp:556
QMultiHash< QString, Method >::const_iterator constEnd() const
Definition qqmlsa.cpp:544
MethodsPrivate(QQmlSA::Method::Methods *, const MethodsPrivate &)
Definition qqmlsa.cpp:551
QMultiHash< QString, Method >::const_iterator constBegin() const
Definition qqmlsa.cpp:525
\inmodule QtQmlCompiler
Definition qqmlsa_p.h:156
PropertyPrivate(Property *, const PropertyPrivate &)
Definition qqmlsa.cpp:713
PropertyPrivate(Property *, PropertyPrivate &&)
Definition qqmlsa.cpp:718
QQmlSA::Element type() const
Returns the type that this property was defined with.
Definition qqmlsa.cpp:746
bool isValid() const
Definition qqmlsa.cpp:728
QString typeName() const
Definition qqmlsa.cpp:723
bool isReadonly() const
Returns whether this property is readonly.
Definition qqmlsa.cpp:738
\inmodule QtQmlCompiler
MethodType
Definition qqmlsa.h:48
Q_QMLCOMPILER_EXPORT void emitWarningWithOptionalFix(GenericPass &pass, QAnyStringView diagnostic, const LoggerWarningId &id, const QQmlSA::SourceLocation &srcLocation, const std::optional< QQmlJSFixSuggestion > &fix)
Definition qqmlsa.cpp:2242
@ Register
Definition qqmlsa.cpp:1456
static QQmlJS::ChildScopesIterator childScopesEnd(const Element &element)
Definition qqmlsa.cpp:1616
static QQmlJS::ChildScopesIterator childScopesBegin(const Element &element)
Definition qqmlsa.cpp:1611
bool isRegularBindingType(BindingType type)
Definition qqmlsa.cpp:2258
static QString lookupName(const QQmlSA::Element &element, LookupMode mode=Lookup)
Definition qqmlsa.cpp:1457
Combined button and popup list for selecting options.