1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "NamePrettyPrinter.h"
27
28 #include "Overview.h"
29
30 #include <cplusplus/Names.h>
31 #include <cplusplus/NameVisitor.h>
32 #include <cplusplus/Literals.h>
33
34 using namespace CPlusPlus;
35
NamePrettyPrinter(const Overview * overview)36 NamePrettyPrinter::NamePrettyPrinter(const Overview *overview)
37 : _overview(overview)
38 { }
39
~NamePrettyPrinter()40 NamePrettyPrinter::~NamePrettyPrinter()
41 { }
42
overview() const43 const Overview *NamePrettyPrinter::overview() const
44 {
45 return _overview;
46 }
47
operator ()(const Name * name)48 QString NamePrettyPrinter::operator()(const Name *name)
49 {
50 QString previousName = switchName();
51 accept(name);
52 return switchName(previousName);
53 }
54
switchName(const QString & name)55 QString NamePrettyPrinter::switchName(const QString &name)
56 {
57 QString previousName = _name;
58 _name = name;
59 return previousName;
60 }
61
visit(const Identifier * name)62 void NamePrettyPrinter::visit(const Identifier *name)
63 {
64 const Identifier *id = name->identifier();
65 if (id)
66 _name = QString::fromUtf8(id->chars(), id->size());
67 else
68 _name = QLatin1String("anonymous");
69 }
70
visit(const TemplateNameId * name)71 void NamePrettyPrinter::visit(const TemplateNameId *name)
72 {
73 const Identifier *id = name->identifier();
74 if (id)
75 _name = QString::fromUtf8(id->chars(), id->size());
76 else
77 _name = QLatin1String("anonymous");
78 if (!_overview->showTemplateParameters)
79 return;
80 _name += QLatin1Char('<');
81 for (int index = 0; index < name->templateArgumentCount(); ++index) {
82 if (index != 0)
83 _name += QLatin1String(", ");
84
85 TemplateArgument templArg = name->templateArgumentAt(index);
86 QString arg;
87 if (templArg.type().isValid())
88 arg = overview()->prettyType(templArg.type());
89 else if (const NumericLiteral *num = templArg.numericLiteral())
90 arg = QString::fromLatin1(num->chars(), num->size());
91
92 if (arg.isEmpty())
93 _name += QString::fromLatin1("_Tp%1").arg(index + 1);
94 else
95 _name += arg;
96 }
97 if (! _name.isEmpty() && _name.at(_name.length() - 1) == QLatin1Char('>'))
98 _name += QLatin1Char(' ');
99 _name += QLatin1Char('>');
100 }
101
visit(const DestructorNameId * name)102 void NamePrettyPrinter::visit(const DestructorNameId *name)
103 {
104 const Identifier *id = name->identifier();
105 _name += QLatin1Char('~');
106 _name += QString::fromUtf8(id->chars(), id->size());
107 }
108
visit(const OperatorNameId * name)109 void NamePrettyPrinter::visit(const OperatorNameId *name)
110 {
111 _name += QLatin1String("operator");
112 if (_overview->includeWhiteSpaceInOperatorName)
113 _name += QLatin1Char(' ');
114 switch (name->kind()) { // ### i should probably do this in OperatorNameId
115 case OperatorNameId::InvalidOp:
116 _name += QLatin1String("<invalid>");
117 break;
118 case OperatorNameId::NewOp:
119 _name += QLatin1String("new");
120 break;
121 case OperatorNameId::DeleteOp:
122 _name += QLatin1String("delete");
123 break;
124 case OperatorNameId::NewArrayOp:
125 _name += QLatin1String("new[]");
126 break;
127 case OperatorNameId::DeleteArrayOp:
128 _name += QLatin1String("delete[]");
129 break;
130 case OperatorNameId::PlusOp:
131 _name += QLatin1Char('+');
132 break;
133 case OperatorNameId::MinusOp:
134 _name += QLatin1Char('-');
135 break;
136 case OperatorNameId::StarOp:
137 _name += QLatin1Char('*');
138 break;
139 case OperatorNameId::SlashOp:
140 _name += QLatin1Char('/');
141 break;
142 case OperatorNameId::PercentOp:
143 _name += QLatin1Char('%');
144 break;
145 case OperatorNameId::CaretOp:
146 _name += QLatin1Char('^');
147 break;
148 case OperatorNameId::AmpOp:
149 _name += QLatin1Char('&');
150 break;
151 case OperatorNameId::PipeOp:
152 _name += QLatin1Char('|');
153 break;
154 case OperatorNameId::TildeOp:
155 _name += QLatin1Char('~');
156 break;
157 case OperatorNameId::ExclaimOp:
158 _name += QLatin1Char('!');
159 break;
160 case OperatorNameId::EqualOp:
161 _name += QLatin1Char('=');
162 break;
163 case OperatorNameId::LessOp:
164 _name += QLatin1Char('<');
165 break;
166 case OperatorNameId::GreaterOp:
167 _name += QLatin1Char('>');
168 break;
169 case OperatorNameId::PlusEqualOp:
170 _name += QLatin1String("+=");
171 break;
172 case OperatorNameId::MinusEqualOp:
173 _name += QLatin1String("-=");
174 break;
175 case OperatorNameId::StarEqualOp:
176 _name += QLatin1String("*=");
177 break;
178 case OperatorNameId::SlashEqualOp:
179 _name += QLatin1String("/=");
180 break;
181 case OperatorNameId::PercentEqualOp:
182 _name += QLatin1String("%=");
183 break;
184 case OperatorNameId::CaretEqualOp:
185 _name += QLatin1String("^=");
186 break;
187 case OperatorNameId::AmpEqualOp:
188 _name += QLatin1String("&=");
189 break;
190 case OperatorNameId::PipeEqualOp:
191 _name += QLatin1String("|=");
192 break;
193 case OperatorNameId::LessLessOp:
194 _name += QLatin1String("<<");
195 break;
196 case OperatorNameId::GreaterGreaterOp:
197 _name += QLatin1String(">>");
198 break;
199 case OperatorNameId::LessLessEqualOp:
200 _name += QLatin1String("<<=");
201 break;
202 case OperatorNameId::GreaterGreaterEqualOp:
203 _name += QLatin1String(">>=");
204 break;
205 case OperatorNameId::EqualEqualOp:
206 _name += QLatin1String("==");
207 break;
208 case OperatorNameId::ExclaimEqualOp:
209 _name += QLatin1String("!=");
210 break;
211 case OperatorNameId::LessEqualOp:
212 _name += QLatin1String("<=");
213 break;
214 case OperatorNameId::GreaterEqualOp:
215 _name += QLatin1String(">=");
216 break;
217 case OperatorNameId::AmpAmpOp:
218 _name += QLatin1String("&&");
219 break;
220 case OperatorNameId::PipePipeOp:
221 _name += QLatin1String("||");
222 break;
223 case OperatorNameId::PlusPlusOp:
224 _name += QLatin1String("++");
225 break;
226 case OperatorNameId::MinusMinusOp:
227 _name += QLatin1String("--");
228 break;
229 case OperatorNameId::CommaOp:
230 _name += QLatin1Char(',');
231 break;
232 case OperatorNameId::ArrowStarOp:
233 _name += QLatin1String("->*");
234 break;
235 case OperatorNameId::ArrowOp:
236 _name += QLatin1String("->");
237 break;
238 case OperatorNameId::FunctionCallOp:
239 _name += QLatin1String("()");
240 break;
241 case OperatorNameId::ArrayAccessOp:
242 _name += QLatin1String("[]");
243 break;
244 } // switch
245 }
246
visit(const ConversionNameId * name)247 void NamePrettyPrinter::visit(const ConversionNameId *name)
248 {
249 _name += QLatin1String("operator ");
250 _name += overview()->prettyType(name->type());
251 }
252
visit(const QualifiedNameId * name)253 void NamePrettyPrinter::visit(const QualifiedNameId *name)
254 {
255 if (name->base())
256 _name += operator()(name->base());
257 _name += QLatin1String("::");
258 _name += operator()(name->name());
259 }
260
visit(const SelectorNameId * name)261 void NamePrettyPrinter::visit(const SelectorNameId *name)
262 {
263 for (int i = 0; i < name->nameCount(); ++i) {
264 const Name *n = name->nameAt(i);
265 if (!n)
266 continue;
267
268 if (const Identifier *id = n->identifier()) {
269 _name += QString::fromUtf8(id->chars(), id->size());
270
271 if (name->hasArguments() || name->nameCount() > 1)
272 _name += QLatin1Char(':');
273 }
274 }
275 }
276
visit(const AnonymousNameId * name)277 void NamePrettyPrinter::visit(const AnonymousNameId *name)
278 {
279 _name = QString::fromLatin1("Anonymous:%1").arg(name->classTokenIndex());
280 }
281