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