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#include "importedmembersvisitor.h"
30#include "scopetree.h"
31
32using namespace QQmlJS::AST;
33
34ScopeTree *ImportedMembersVisitor::result(const QString &scopeName) const
35{
36 ScopeTree *result = new ScopeTree(ScopeType::QMLScope);
37 result->setClassName(scopeName);
38 result->setSuperclassName(m_rootObject->superclassName());
39 const auto properties = m_rootObject->properties();
40 for (auto property : properties) {
41 if (property.isAlias()) {
42 const auto it = m_objects.find(akey: property.typeName());
43 if (it != m_objects.end())
44 property.setType(it->get());
45 result->addProperty(prop: property);
46 } else {
47 result->addProperty(prop: property);
48 }
49 }
50
51 for (const auto &method : m_rootObject->methods())
52 result->addMethod(method);
53
54 return result;
55}
56
57bool ImportedMembersVisitor::visit(UiObjectDefinition *definition)
58{
59 ScopeTree::Ptr scope(new ScopeTree(ScopeType::QMLScope));
60 QString superType;
61 for (auto segment = definition->qualifiedTypeNameId; segment; segment = segment->next) {
62 if (!superType.isEmpty())
63 superType.append(c: '.');
64 superType.append(s: segment->name.toString());
65 }
66 scope->setSuperclassName(superType);
67 if (!m_rootObject)
68 m_rootObject = scope;
69 m_currentObjects.append(t: scope);
70 return true;
71}
72
73void ImportedMembersVisitor::endVisit(UiObjectDefinition *)
74{
75 m_currentObjects.pop_back();
76}
77
78bool ImportedMembersVisitor::visit(UiPublicMember *publicMember)
79{
80 switch (publicMember->type) {
81 case UiPublicMember::Signal: {
82 UiParameterList *param = publicMember->parameters;
83 MetaMethod method;
84 method.setMethodType(MetaMethod::Signal);
85 method.setMethodName(publicMember->name.toString());
86 while (param) {
87 method.addParameter(name: param->name.toString(), type: param->type->name.toString());
88 param = param->next;
89 }
90 currentObject()->addMethod(method);
91 break;
92 }
93 case UiPublicMember::Property: {
94 auto typeName = publicMember->memberType->name;
95 const bool isAlias = (typeName == QLatin1String("alias"));
96 if (isAlias) {
97 const auto expression = cast<ExpressionStatement *>(ast: publicMember->statement);
98 if (const auto idExpression = cast<IdentifierExpression *>(ast: expression->expression))
99 typeName = idExpression->name;
100 }
101 MetaProperty prop {
102 publicMember->name.toString(),
103 typeName.toString(),
104 false,
105 false,
106 false,
107 isAlias,
108 0
109 };
110 currentObject()->addProperty(prop);
111 break;
112 }
113 }
114 return true;
115}
116
117bool ImportedMembersVisitor::visit(UiSourceElement *sourceElement)
118{
119 if (FunctionExpression *fexpr = sourceElement->sourceElement->asFunctionDefinition()) {
120 MetaMethod method;
121 method.setMethodName(fexpr->name.toString());
122 method.setMethodType(MetaMethod::Method);
123 FormalParameterList *parameters = fexpr->formals;
124 while (parameters) {
125 method.addParameter(name: parameters->element->bindingIdentifier.toString(), type: "");
126 parameters = parameters->next;
127 }
128 currentObject()->addMethod(method);
129 } else if (ClassExpression *clexpr = sourceElement->sourceElement->asClassDefinition()) {
130 MetaProperty prop { clexpr->name.toString(), "", false, false, false, false, 1 };
131 currentObject()->addProperty(prop);
132 } else if (cast<VariableStatement *>(ast: sourceElement->sourceElement)) {
133 // nothing to do
134 } else {
135 const auto loc = sourceElement->firstSourceLocation();
136 m_colorOut->writeUncolored(
137 message: "unsupportedd sourceElement at "
138 + QString::fromLatin1(str: "%1:%2: ").arg(a: loc.startLine).arg(a: loc.startColumn)
139 + QString::number(sourceElement->sourceElement->kind));
140 }
141 return true;
142}
143
144bool ImportedMembersVisitor::visit(UiScriptBinding *scriptBinding)
145{
146 if (scriptBinding->qualifiedId->name == QLatin1String("id")) {
147 const auto *statement = cast<ExpressionStatement *>(ast: scriptBinding->statement);
148 const auto *idExprension = cast<IdentifierExpression *>(ast: statement->expression);
149 m_objects.insert(akey: idExprension->name.toString(), avalue: currentObject());
150 }
151 return true;
152}
153
154void ImportedMembersVisitor::throwRecursionDepthError()
155{
156 m_colorOut->write(QStringLiteral("Error"), color: Error);
157 m_colorOut->write(QStringLiteral("Maximum statement or expression depth exceeded"), color: Error);
158}
159

source code of qtdeclarative/tools/qmllint/importedmembersvisitor.cpp