Improved the type pretty printer.

This commit is contained in:
Roberto Raggi
2009-02-13 15:37:42 +01:00
parent 1f9a83e073
commit e801434799
4 changed files with 156 additions and 126 deletions

View File

@@ -68,6 +68,11 @@ bool Overview::showReturnTypes() const
return _showReturnTypes; return _showReturnTypes;
} }
unsigned Overview::markArgument() const
{
return _markArgument;
}
void Overview::setMarkArgument(unsigned position) void Overview::setMarkArgument(unsigned position)
{ {
_markArgument = position; _markArgument = position;
@@ -98,9 +103,5 @@ QString Overview::prettyType(const FullySpecifiedType &ty,
const QString &name) const const QString &name) const
{ {
TypePrettyPrinter pp(this); TypePrettyPrinter pp(this);
pp.setMarkArgument(_markArgument);
pp.setShowArgumentNames(_showArgumentNames);
pp.setShowReturnTypes(_showReturnTypes);
pp.setShowFunctionSignatures(_showFunctionSignatures);
return pp(ty, name); return pp(ty, name);
} }

View File

@@ -57,7 +57,10 @@ public:
bool showFunctionSignatures() const; bool showFunctionSignatures() const;
void setShowFunctionSignatures(bool showFunctionSignatures); void setShowFunctionSignatures(bool showFunctionSignatures);
void setMarkArgument(unsigned position); // 1-based // 1-based
// ### rename
unsigned markArgument() const;
void setMarkArgument(unsigned position);
QString operator()(Name *name) const QString operator()(Name *name) const
{ return prettyName(name); } { return prettyName(name); }

View File

@@ -42,37 +42,12 @@ using namespace CPlusPlus;
TypePrettyPrinter::TypePrettyPrinter(const Overview *overview) TypePrettyPrinter::TypePrettyPrinter(const Overview *overview)
: _overview(overview), : _overview(overview),
_name(0), _name(0)
_markArgument(0),
_showArgumentNames(false),
_showReturnTypes(false),
_showFunctionSignatures(true)
{ } { }
TypePrettyPrinter::~TypePrettyPrinter() TypePrettyPrinter::~TypePrettyPrinter()
{ } { }
bool TypePrettyPrinter::showArgumentNames() const
{ return _showArgumentNames; }
void TypePrettyPrinter::setShowArgumentNames(bool showArgumentNames)
{ _showArgumentNames = showArgumentNames; }
bool TypePrettyPrinter::showReturnTypes() const
{ return _showReturnTypes; }
void TypePrettyPrinter::setShowReturnTypes(bool showReturnTypes)
{ _showReturnTypes = showReturnTypes; }
bool TypePrettyPrinter::showFunctionSignatures() const
{ return _showFunctionSignatures; }
void TypePrettyPrinter::setShowFunctionSignatures(bool showFunctionSignatures)
{ _showFunctionSignatures = showFunctionSignatures; }
void TypePrettyPrinter::setMarkArgument(unsigned position)
{ _markArgument = position; }
const Overview *TypePrettyPrinter::overview() const const Overview *TypePrettyPrinter::overview() const
{ return _overview; } { return _overview; }
@@ -102,15 +77,16 @@ QString TypePrettyPrinter::operator()(const FullySpecifiedType &type, const QStr
void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty) void TypePrettyPrinter::acceptType(const FullySpecifiedType &ty)
{ {
if (ty.isConst())
_text += QLatin1String("const ");
if (ty.isVolatile())
_text += QLatin1String("volatile ");
if (ty.isSigned()) if (ty.isSigned())
_text += QLatin1String("signed "); out(QLatin1String("signed "));
if (ty.isUnsigned())
_text += QLatin1String("unsigned "); else if (ty.isUnsigned())
out(QLatin1String("unsigned "));
const FullySpecifiedType previousFullySpecifiedType = _fullySpecifiedType;
_fullySpecifiedType = ty;
accept(ty.type()); accept(ty.type());
_fullySpecifiedType = previousFullySpecifiedType;
} }
QString TypePrettyPrinter::switchName(const QString &name) QString TypePrettyPrinter::switchName(const QString &name)
@@ -127,9 +103,9 @@ QString TypePrettyPrinter::switchText(const QString &name)
return previousName; return previousName;
} }
QList<Type *> TypePrettyPrinter::switchPtrOperators(const QList<Type *> &ptrOperators) QList<FullySpecifiedType> TypePrettyPrinter::switchPtrOperators(const QList<FullySpecifiedType> &ptrOperators)
{ {
QList<Type *> previousPtrOperators = _ptrOperators; QList<FullySpecifiedType> previousPtrOperators = _ptrOperators;
_ptrOperators = ptrOperators; _ptrOperators = ptrOperators;
return previousPtrOperators; return previousPtrOperators;
} }
@@ -137,31 +113,53 @@ QList<Type *> TypePrettyPrinter::switchPtrOperators(const QList<Type *> &ptrOper
void TypePrettyPrinter::applyPtrOperators(bool wantSpace) void TypePrettyPrinter::applyPtrOperators(bool wantSpace)
{ {
for (int i = _ptrOperators.size() - 1; i != -1; --i) { for (int i = _ptrOperators.size() - 1; i != -1; --i) {
Type *op = _ptrOperators.at(i); const FullySpecifiedType op = _ptrOperators.at(i);
if (i == 0 && wantSpace) if (i == 0 && wantSpace)
_text += QLatin1Char(' '); space();
if (PointerType *ptrTy = op->asPointerType()) { if (op->isPointerType()) {
_text += QLatin1Char('*'); out(QLatin1Char('*'));
if (ptrTy->elementType().isConst()) outCV(op);
_text += " const";
if (ptrTy->elementType().isVolatile())
_text += " volatile";
} else if (op->isReferenceType()) { } else if (op->isReferenceType()) {
_text += QLatin1Char('&'); out(QLatin1Char('&'));
} else if (PointerToMemberType *memPtrTy = op->asPointerToMemberType()) { } else if (const PointerToMemberType *memPtrTy = op->asPointerToMemberType()) {
_text += QLatin1Char(' '); space();
_text += _overview->prettyName(memPtrTy->memberName()); out(_overview->prettyName(memPtrTy->memberName()));
_text += QLatin1Char('*'); out(QLatin1Char('*'));
outCV(op);
} }
} }
} }
void TypePrettyPrinter::visit(VoidType *) void TypePrettyPrinter::visit(VoidType *)
{ {
_text += QLatin1String("void"); out(QLatin1String("void"));
applyPtrOperators();
}
void TypePrettyPrinter::visit(NamedType *type)
{
out(overview()->prettyName(type->name()));
applyPtrOperators();
}
void TypePrettyPrinter::visit(Namespace *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators();
}
void TypePrettyPrinter::visit(Class *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators();
}
void TypePrettyPrinter::visit(Enum *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators(); applyPtrOperators();
} }
@@ -169,25 +167,25 @@ void TypePrettyPrinter::visit(IntegerType *type)
{ {
switch (type->kind()) { switch (type->kind()) {
case IntegerType::Char: case IntegerType::Char:
_text += QLatin1String("char"); out(QLatin1String("char"));
break; break;
case IntegerType::WideChar: case IntegerType::WideChar:
_text += QLatin1String("wchar_t"); out(QLatin1String("wchar_t"));
break; break;
case IntegerType::Bool: case IntegerType::Bool:
_text += QLatin1String("bool"); out(QLatin1String("bool"));
break; break;
case IntegerType::Short: case IntegerType::Short:
_text += QLatin1String("short"); out(QLatin1String("short"));
break; break;
case IntegerType::Int: case IntegerType::Int:
_text += QLatin1String("int"); out(QLatin1String("int"));
break; break;
case IntegerType::Long: case IntegerType::Long:
_text += QLatin1String("long"); out(QLatin1String("long"));
break; break;
case IntegerType::LongLong: case IntegerType::LongLong:
_text += QLatin1String("long long"); out(QLatin1String("long long"));
break; break;
} }
@@ -198,13 +196,13 @@ void TypePrettyPrinter::visit(FloatType *type)
{ {
switch (type->kind()) { switch (type->kind()) {
case FloatType::Float: case FloatType::Float:
_text += QLatin1String("float"); out(QLatin1String("float"));
break; break;
case FloatType::Double: case FloatType::Double:
_text += QLatin1String("double"); out(QLatin1String("double"));
break; break;
case FloatType::LongDouble: case FloatType::LongDouble:
_text += QLatin1String("long double"); out(QLatin1String("long double"));
break; break;
} }
@@ -213,99 +211,135 @@ void TypePrettyPrinter::visit(FloatType *type)
void TypePrettyPrinter::visit(PointerToMemberType *type) void TypePrettyPrinter::visit(PointerToMemberType *type)
{ {
_ptrOperators.append(type); outCV(type->elementType());
space();
_ptrOperators.append(_fullySpecifiedType);
acceptType(type->elementType()); acceptType(type->elementType());
} }
void TypePrettyPrinter::visit(PointerType *type) void TypePrettyPrinter::visit(PointerType *type)
{ {
_ptrOperators.append(type); outCV(type->elementType());
space();
_ptrOperators.append(_fullySpecifiedType);
acceptType(type->elementType()); acceptType(type->elementType());
} }
void TypePrettyPrinter::visit(ReferenceType *type) void TypePrettyPrinter::visit(ReferenceType *type)
{ {
_ptrOperators.append(type); outCV(type->elementType());
space();
_ptrOperators.append(_fullySpecifiedType);
acceptType(type->elementType()); acceptType(type->elementType());
} }
void TypePrettyPrinter::visit(ArrayType *type) void TypePrettyPrinter::visit(ArrayType *type)
{ {
_text += overview()->prettyType(type->elementType()); out(overview()->prettyType(type->elementType()));
if (! _ptrOperators.isEmpty()) { if (! _ptrOperators.isEmpty()) {
_text += QLatin1Char('('); out(QLatin1Char('('));
applyPtrOperators(false); applyPtrOperators(false);
if (! _name.isEmpty()) { if (! _name.isEmpty()) {
_text += _name; out(_name);
_name.clear(); _name.clear();
} }
_text += QLatin1Char(')'); out(QLatin1Char(')'));
} }
_text += QLatin1String("[]"); out(QLatin1String("[]"));
}
void TypePrettyPrinter::visit(NamedType *type)
{
_text += overview()->prettyName(type->name());
applyPtrOperators();
} }
void TypePrettyPrinter::visit(Function *type) void TypePrettyPrinter::visit(Function *type)
{ {
if (_showReturnTypes) if (_overview->showReturnTypes())
_text += _overview->prettyType(type->returnType()); out(_overview->prettyType(type->returnType()));
if (! _ptrOperators.isEmpty()) { if (! _ptrOperators.isEmpty()) {
_text += QLatin1Char('('); out(QLatin1Char('('));
applyPtrOperators(false); applyPtrOperators(false);
if (! _name.isEmpty()) { if (! _name.isEmpty()) {
_text += _name; _text += _name;
_name.clear(); _name.clear();
} }
_text += QLatin1Char(')'); out(QLatin1Char(')'));
} else if (! _name.isEmpty() && _showFunctionSignatures) { } else if (! _name.isEmpty() && _overview->showFunctionSignatures()) {
_text += QLatin1Char(' '); // ### fixme space();
_text += _name; out(_name);
_name.clear(); _name.clear();
} }
if (_showFunctionSignatures) { if (_overview->showFunctionSignatures()) {
Overview argumentText; Overview argumentText;
_text += QLatin1Char('('); argumentText.setShowReturnTypes(true);
argumentText.setShowArgumentNames(false);
argumentText.setShowFunctionSignatures(true);
out(QLatin1Char('('));
for (unsigned index = 0; index < type->argumentCount(); ++index) { for (unsigned index = 0; index < type->argumentCount(); ++index) {
if (index != 0) if (index != 0)
_text += QLatin1String(", "); out(QLatin1String(", "));
if (Argument *arg = type->argumentAt(index)->asArgument()) { if (Argument *arg = type->argumentAt(index)->asArgument()) {
if (index + 1 == _markArgument) if (index + 1 == _overview->markArgument())
_text += QLatin1String("<b>"); out(QLatin1String("<b>"));
Name *name = 0; Name *name = 0;
if (_showArgumentNames)
if (_overview->showArgumentNames())
name = arg->name(); name = arg->name();
_text += argumentText(arg->type(), name);
if (index + 1 == _markArgument) out(argumentText(arg->type(), name));
_text += QLatin1String("</b>");
if (index + 1 == _overview->markArgument())
out(QLatin1String("</b>"));
} }
} }
if (type->isVariadic()) if (type->isVariadic())
_text += QLatin1String("..."); out(QLatin1String("..."));
_text += QLatin1Char(')'); out(QLatin1Char(')'));
if (type->isConst() && type->isVolatile()) {
if (type->isConst()) space();
_text += QLatin1String(" const"); out("const volatile");
} else if (type->isConst()) {
if (type->isVolatile()) space();
_text += QLatin1String(" volatile"); out("const");
} else if (type->isVolatile()) {
space();
out("volatile");
}
} }
} }
void TypePrettyPrinter::visit(Namespace *type) void TypePrettyPrinter::space()
{ _text += overview()->prettyName(type->name()); } {
if (_text.isEmpty())
return;
void TypePrettyPrinter::visit(Class *type) const QChar ch = _text.at(_text.length() - 1);
{ _text += overview()->prettyName(type->name()); }
void TypePrettyPrinter::visit(Enum *type) if (ch.isLetterOrNumber() || ch == QLatin1Char('_') || ch == QLatin1Char(')'))
{ _text += overview()->prettyName(type->name()); } _text += QLatin1Char(' ');
}
void TypePrettyPrinter::out(const QString &text)
{ _text += text; }
void TypePrettyPrinter::out(const QChar &ch)
{ _text += ch; }
void TypePrettyPrinter::outCV(const FullySpecifiedType &ty)
{
if (ty.isConst() && ty.isVolatile())
out(QLatin1String("const volatile"));
else if (ty.isConst())
out(QLatin1String("const"));
else if (ty.isVolatile())
out(QLatin1String("volatile"));
}

View File

@@ -33,7 +33,8 @@
#ifndef TYPEPRETTYPRINTER_H #ifndef TYPEPRETTYPRINTER_H
#define TYPEPRETTYPRINTER_H #define TYPEPRETTYPRINTER_H
#include "TypeVisitor.h" #include <TypeVisitor.h>
#include <FullySpecifiedType.h>
#include <QString> #include <QString>
#include <QList> #include <QList>
@@ -50,23 +51,12 @@ public:
const Overview *overview() const; const Overview *overview() const;
bool showArgumentNames() const;
void setShowArgumentNames(bool showArgumentNames);
bool showReturnTypes() const;
void setShowReturnTypes(bool showReturnTypes);
bool showFunctionSignatures() const;
void setShowFunctionSignatures(bool showFunctionSignatures);
void setMarkArgument(unsigned position); // 1-based
QString operator()(const FullySpecifiedType &type); QString operator()(const FullySpecifiedType &type);
QString operator()(const FullySpecifiedType &type, const QString &name); QString operator()(const FullySpecifiedType &type, const QString &name);
protected: protected:
QString switchText(const QString &text = QString()); QString switchText(const QString &text = QString());
QList<Type *> switchPtrOperators(const QList<Type *> &ptrOperators); QList<FullySpecifiedType> switchPtrOperators(const QList<FullySpecifiedType> &ptrOperators);
QString switchName(const QString &name); QString switchName(const QString &name);
void applyPtrOperators(bool wantSpace = true); void applyPtrOperators(bool wantSpace = true);
@@ -85,15 +75,17 @@ protected:
virtual void visit(Class *type); virtual void visit(Class *type);
virtual void visit(Enum *type); virtual void visit(Enum *type);
void space();
void out(const QString &text);
void out(const QChar &ch);
void outCV(const FullySpecifiedType &ty);
private: private:
const Overview *_overview; const Overview *_overview;
QString _name; QString _name;
QString _text; QString _text;
QList<Type *> _ptrOperators; FullySpecifiedType _fullySpecifiedType;
unsigned _markArgument; QList<FullySpecifiedType> _ptrOperators;
bool _showArgumentNames: 1;
bool _showReturnTypes: 1;
bool _showFunctionSignatures: 1;
}; };
} // end of namespace CPlusPlus } // end of namespace CPlusPlus