1/****************************************************************************
2**
3** Copyright (C) 2019 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the tools applications of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#ifndef SCOPETREE_H
30#define SCOPETREE_H
31
32//
33// W A R N I N G
34// -------------
35//
36// This file is not part of the Qt API. It exists purely as an
37// implementation detail. This header file may change from version to
38// version without notice, or even be removed.
39//
40// We mean it.
41
42#include "metatypes.h"
43#include "componentversion.h"
44
45#include <QtQml/private/qqmljsast_p.h>
46#include <QtQml/private/qqmljssourcelocation_p.h>
47
48#include <QtCore/qset.h>
49#include <QtCore/qhash.h>
50#include <QtCore/qstring.h>
51
52enum MessageColors
53{
54 Error,
55 Warning,
56 Info,
57 Normal,
58 Hint
59};
60
61enum class ScopeType
62{
63 JSFunctionScope,
64 JSLexicalScope,
65 QMLScope
66};
67
68struct MethodUsage
69{
70 MetaMethod method;
71 QQmlJS::SourceLocation loc;
72 bool hasMultilineHandlerBody;
73};
74
75class ColorOutput;
76class ScopeTree
77{
78 Q_DISABLE_COPY_MOVE(ScopeTree)
79public:
80 using Ptr = QSharedPointer<ScopeTree>;
81 using ConstPtr = QSharedPointer<const ScopeTree>;
82
83 class Export {
84 public:
85 Export() = default;
86 Export(QString package, QString type, const ComponentVersion &version,
87 int metaObjectRevision);
88
89 bool isValid() const;
90
91 int metaObjectRevision() const { return m_metaObjectRevision; }
92 void setMetaObjectRevision(int metaObjectRevision)
93 {
94 m_metaObjectRevision = metaObjectRevision;
95 }
96
97 QString package() const { return m_package; }
98 QString type() const { return m_type; }
99
100 private:
101 QString m_package;
102 QString m_type;
103 ComponentVersion m_version;
104 int m_metaObjectRevision = 0;
105 };
106
107 ScopeTree(ScopeType type, QString name = QString(),
108 ScopeTree *parentScope = nullptr);
109
110 ScopeTree::Ptr createNewChildScope(ScopeType type, const QString &name);
111 ScopeTree *parentScope() const { return m_parentScope; }
112
113 void insertJSIdentifier(const QString &id, QQmlJS::AST::VariableScope scope);
114 void insertSignalIdentifier(const QString &id, const MetaMethod &method,
115 const QQmlJS::SourceLocation &loc, bool hasMultilineHandlerBody);
116 // inserts property as qml identifier as well as the corresponding
117 void insertPropertyIdentifier(const MetaProperty &prop);
118 void addUnmatchedSignalHandler(const QString &handler,
119 const QQmlJS::SourceLocation &location);
120
121 bool isIdInCurrentScope(const QString &id) const;
122 void addIdToAccessed(const QString &id, const QQmlJS::SourceLocation &location);
123 void accessMember(const QString &name, const QString &parentType,
124 const QQmlJS::SourceLocation &location);
125 void resetMemberScope();
126
127 bool isVisualRootScope() const;
128 QString name() const { return m_name; }
129
130 bool recheckIdentifiers(
131 const QString &code,
132 const QHash<QString, const ScopeTree *> &qmlIDs,
133 const QHash<QString, ScopeTree::ConstPtr> &types,
134 const ScopeTree *root, const QString& rootId, ColorOutput &colorOut) const;
135
136 ScopeType scopeType() const { return m_scopeType; }
137
138 void addMethods(const QHash<QString, MetaMethod> &methods) { m_methods.insert(hash: methods); }
139 void addMethod(const MetaMethod &method) { m_methods.insert(akey: method.methodName(), avalue: method); }
140 QHash<QString, MetaMethod> methods() const { return m_methods; }
141
142 void addEnum(const MetaEnum &fakeEnum) { m_enums.insert(akey: fakeEnum.name(), avalue: fakeEnum); }
143 QHash<QString, MetaEnum> enums() const { return m_enums; }
144
145 QString className() const { return m_className; }
146 void setClassName(const QString &name) { m_className = name; }
147
148 void addExport(const QString &name, const QString &package, const ComponentVersion &version);
149 void setExportMetaObjectRevision(int exportIndex, int metaObjectRevision);
150 QList<Export> exports() const { return m_exports; }
151
152 void setSuperclassName(const QString &superclass) { m_superName = superclass; }
153 QString superclassName() const { return m_superName; }
154
155 void addProperty(const MetaProperty &prop) { m_properties.insert(akey: prop.propertyName(), avalue: prop); }
156 QHash<QString, MetaProperty> properties() const { return m_properties; }
157 void updateParentProperty(const ScopeTree *scope);
158
159 QString defaultPropertyName() const { return m_defaultPropertyName; }
160 void setDefaultPropertyName(const QString &name) { m_defaultPropertyName = name; }
161
162 QString attachedTypeName() const { return m_attachedTypeName; }
163 void setAttachedTypeName(const QString &name) { m_attachedTypeName = name; }
164
165 bool isSingleton() const { return m_isSingleton; }
166 bool isCreatable() const { return m_isCreatable; }
167 bool isComposite() const { return m_isComposite; }
168 void setIsSingleton(bool value) { m_isSingleton = value; }
169 void setIsCreatable(bool value) { m_isCreatable = value; }
170 void setIsComposite(bool value) { m_isSingleton = value; }
171
172private:
173 struct FieldMemberList
174 {
175 QString m_name;
176 QString m_parentType;
177 QQmlJS::SourceLocation m_location;
178 std::unique_ptr<FieldMemberList> m_child;
179 };
180
181 QSet<QString> m_jsIdentifiers;
182 QMultiHash<QString, MethodUsage> m_injectedSignalIdentifiers;
183
184 QHash<QString, MetaMethod> m_methods;
185 QHash<QString, MetaProperty> m_properties;
186 QHash<QString, MetaEnum> m_enums;
187
188 std::vector<std::unique_ptr<FieldMemberList>> m_accessedIdentifiers;
189 FieldMemberList *m_currentFieldMember = nullptr;
190
191 QVector<QPair<QString, QQmlJS::SourceLocation>> m_unmatchedSignalHandlers;
192
193 QVector<ScopeTree::Ptr> m_childScopes;
194 ScopeTree *m_parentScope;
195
196 QString m_name;
197 QString m_className;
198 QString m_superName;
199
200 ScopeType m_scopeType = ScopeType::QMLScope;
201 QList<Export> m_exports;
202
203 QString m_defaultPropertyName;
204 QString m_attachedTypeName;
205 bool m_isSingleton = false;
206 bool m_isCreatable = true;
207 bool m_isComposite = false;
208
209 bool isIdInCurrentQMlScopes(const QString &id) const;
210 bool isIdInCurrentJSScopes(const QString &id) const;
211 bool isIdInjectedFromSignal(const QString &id) const;
212 const ScopeTree *currentQMLScope() const;
213 void printContext(ColorOutput &colorOut, const QString &code,
214 const QQmlJS::SourceLocation &location) const;
215 bool checkMemberAccess(
216 const QString &code,
217 FieldMemberList *members,
218 const ScopeTree *scope,
219 const QHash<QString, ScopeTree::ConstPtr> &types,
220 ColorOutput& colorOut) const;
221};
222
223#endif // SCOPETREE_H
224

source code of qtdeclarative/tools/qmllint/scopetree.h