413 lines
11 KiB
C++
413 lines
11 KiB
C++
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2006-2009 fullmetalcoder <fullmetalcoder@hotmail.fr>
|
|
**
|
|
** This file is part of the Edyuk project <http://edyuk.org>
|
|
**
|
|
** This file may be used under the terms of the GNU General Public License
|
|
** version 3 as published by the Free Software Foundation and appearing in the
|
|
** file GPL.txt included in the packaging of this file.
|
|
**
|
|
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
**
|
|
****************************************************************************/
|
|
|
|
#include "qcodenode.h"
|
|
|
|
#include <QIcon>
|
|
#include <QVariant>
|
|
|
|
enum CacheIndex {
|
|
ICON_ENUM,
|
|
ICON_ENUMERATOR,
|
|
// ICON_UNION,
|
|
ICON_CLASS,
|
|
// ICON_STRUCT,
|
|
ICON_TYPEDEF,
|
|
ICON_NAMESPACE,
|
|
ICON_FUNCTION = ICON_NAMESPACE + 2,
|
|
ICON_VARIABLE = ICON_FUNCTION + 5
|
|
};
|
|
|
|
using IconHash = QHash<int, QIcon>;
|
|
Q_GLOBAL_STATIC(IconHash, q_icon_cache)
|
|
|
|
inline static QIcon getIcon(const QString &name) {
|
|
return QIcon(QStringLiteral(":/completion/images/completion/") + name +
|
|
QStringLiteral(".png"));
|
|
}
|
|
|
|
static QIcon icon(int cacheIndex) {
|
|
static bool setup = false;
|
|
|
|
if (!setup) {
|
|
// q_icon_cache[ICON_UNION] = QIcon(":/completion/CVunion.png");
|
|
|
|
(*q_icon_cache)[ICON_ENUM] = getIcon(QStringLiteral("CVenum"));
|
|
(*q_icon_cache)[ICON_ENUMERATOR] =
|
|
getIcon(QStringLiteral("CVenumerator"));
|
|
|
|
(*q_icon_cache)[ICON_CLASS] = getIcon(QStringLiteral("CVclass"));
|
|
|
|
// q_icon_cache[ICON_STRUCT] = QIcon(":/completion/CVstruct.png");
|
|
|
|
(*q_icon_cache)[ICON_TYPEDEF] = getIcon(QStringLiteral("CVtypedef"));
|
|
|
|
(*q_icon_cache)[ICON_NAMESPACE] =
|
|
getIcon(QStringLiteral("CVnamespace"));
|
|
|
|
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_DEFAULT] =
|
|
getIcon(QStringLiteral("CVglobal_meth"));
|
|
|
|
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PUBLIC] =
|
|
getIcon(QStringLiteral("CVpublic_meth"));
|
|
|
|
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PROTECTED] =
|
|
getIcon(QStringLiteral("CVprotected_meth"));
|
|
|
|
(*q_icon_cache)[ICON_FUNCTION + QCodeNode::VISIBILITY_PRIVATE] =
|
|
getIcon(QStringLiteral("CVprivate_meth"));
|
|
|
|
// q_icon_cache[ICON_FUNCTION + QCodeNode::VISIBILITY_SIGNAL] =
|
|
// QIcon(":/completion/CVprotected_signal.png");
|
|
|
|
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_DEFAULT] =
|
|
getIcon(QStringLiteral("CVglobal_var"));
|
|
|
|
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PUBLIC] =
|
|
getIcon(QStringLiteral("CVpublic_var"));
|
|
|
|
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PROTECTED] =
|
|
getIcon(QStringLiteral("CVprotected_var"));
|
|
|
|
(*q_icon_cache)[ICON_VARIABLE + QCodeNode::VISIBILITY_PRIVATE] =
|
|
getIcon(QStringLiteral("CVprivate_var"));
|
|
|
|
setup = true;
|
|
}
|
|
|
|
return q_icon_cache->value(cacheIndex);
|
|
}
|
|
|
|
QCodeNode::QCodeNode() : line(-1), _parent(nullptr) {}
|
|
|
|
QCodeNode::~QCodeNode() {
|
|
QCodeNode::detach();
|
|
|
|
_parent = nullptr;
|
|
|
|
clear();
|
|
}
|
|
|
|
void QCodeNode::attach(QCodeNode *p) {
|
|
detach();
|
|
|
|
if (!p || p->_children.contains(this))
|
|
return;
|
|
|
|
int row = p->_children.length();
|
|
|
|
_parent = p;
|
|
p->_children.insert(row, this);
|
|
}
|
|
|
|
void QCodeNode::detach() {
|
|
if (!_parent)
|
|
return;
|
|
|
|
int row = _parent->_children.indexOf(this);
|
|
|
|
if (row < 0)
|
|
return;
|
|
|
|
_parent->_children.removeAt(row);
|
|
_parent = 0;
|
|
}
|
|
|
|
QCodeNode *QCodeNode::parent() const { return _parent; }
|
|
|
|
void QCodeNode::setParent(QCodeNode *newParent) { _parent = newParent; }
|
|
|
|
int QCodeNode::getLine() const { return line; }
|
|
|
|
void QCodeNode::setLine(int newLine) { line = newLine; }
|
|
|
|
void QCodeNode::clear() {
|
|
QList<QCodeNode *> c = _children;
|
|
|
|
removeAll();
|
|
|
|
qDeleteAll(c);
|
|
}
|
|
|
|
void QCodeNode::removeAll() {
|
|
if (_children.isEmpty())
|
|
return;
|
|
|
|
for (auto &n : _children) {
|
|
n->_parent = nullptr;
|
|
}
|
|
|
|
_children.clear();
|
|
}
|
|
|
|
int QCodeNode::type() const {
|
|
return roles.value(NodeType, QByteArray(1, 0)).at(0);
|
|
}
|
|
|
|
QByteArray QCodeNode::context() const {
|
|
int t = type();
|
|
|
|
if ((t == Group) || (t == Namespace))
|
|
return QByteArray();
|
|
|
|
const QCodeNode *p = this;
|
|
|
|
while (p->_parent) {
|
|
int t = p->_parent->type();
|
|
|
|
if ((t == Group) || (t == Namespace))
|
|
break;
|
|
|
|
p = p->_parent;
|
|
}
|
|
|
|
return p ? p->role(Context) : role(Context);
|
|
}
|
|
|
|
QByteArray QCodeNode::qualifiedName(bool ext) const {
|
|
int t = type();
|
|
|
|
if (t == Group)
|
|
return QByteArray();
|
|
|
|
QByteArray cxt;
|
|
if (ext) {
|
|
if (_parent && _parent->type() == Namespace) {
|
|
cxt += _parent->role(Name);
|
|
}
|
|
cxt += "::";
|
|
}
|
|
|
|
cxt += role(Name);
|
|
|
|
if (t == Function) {
|
|
cxt += "(";
|
|
cxt += role(Arguments);
|
|
cxt += ")";
|
|
}
|
|
|
|
return cxt;
|
|
}
|
|
|
|
QVariant QCodeNode::data(int r) const {
|
|
const int t = type();
|
|
|
|
switch (r) {
|
|
case Qt::DisplayRole: {
|
|
if (t == Function)
|
|
return role(Name) + "(" + role(Arguments) + ")";
|
|
|
|
return role(Name);
|
|
}
|
|
|
|
case Qt::ToolTipRole:
|
|
case Qt::StatusTipRole: {
|
|
switch (t) {
|
|
case Class: {
|
|
QByteArray d("class ");
|
|
d += role(Name);
|
|
|
|
QByteArray a = role(Ancestors);
|
|
|
|
if (a.length())
|
|
d += " : " + a;
|
|
|
|
return d;
|
|
}
|
|
|
|
// case Struct: {
|
|
// QByteArray d("struct ");
|
|
// d += role(Name);
|
|
|
|
// QByteArray a = role(Ancestors);
|
|
|
|
// if (a.length())
|
|
// d += " : " + a;
|
|
|
|
// return d;
|
|
// }
|
|
|
|
case Enum:
|
|
return QByteArray("enum ") + role(Name);
|
|
|
|
case Enumerator:
|
|
return role(Name) + " = " + role(Value);
|
|
|
|
// case Union:
|
|
// return QByteArray("union ") + role(Name);
|
|
|
|
case Namespace:
|
|
return QByteArray("namespace ") + role(Name);
|
|
|
|
case Typedef:
|
|
return QByteArray("typedef ") + role(Alias) + " " + role(Name);
|
|
|
|
case Variable: {
|
|
QByteArray signature, specifier;
|
|
|
|
signature += role(Type);
|
|
signature += " ";
|
|
signature += role(Name);
|
|
|
|
int m_visibility = role(Visibility).toInt();
|
|
int m_specifiers = role(Specifiers).toInt();
|
|
|
|
// visibility (for class members)
|
|
if (m_visibility == QCodeNode::VISIBILITY_PUBLIC)
|
|
specifier = " public ";
|
|
else if (m_visibility == QCodeNode::VISIBILITY_PROTECTED)
|
|
specifier = " protected ";
|
|
else
|
|
specifier = " private ";
|
|
|
|
// storage class
|
|
if (m_specifiers & QCodeNode::SPECIFIER_AUTO)
|
|
specifier += " auto ";
|
|
// else if (m_specifiers & QCodeNode::SPECIFIER_REGISTER)
|
|
// specifier += " register ";
|
|
else if (m_specifiers & QCodeNode::SPECIFIER_STATIC)
|
|
specifier += " static ";
|
|
else if (m_specifiers & QCodeNode::SPECIFIER_EXTERN)
|
|
specifier += " extern ";
|
|
// else if (m_specifiers & QCodeNode::SPECIFIER_MUTABLE)
|
|
// specifier += " mutable ";
|
|
|
|
// cv qualifier (for class members)
|
|
if (m_specifiers & QCodeNode::SPECIFIER_CONST)
|
|
specifier += " const ";
|
|
// else if (m_specifiers & QCodeNode::SPECIFIER_VOLATILE)
|
|
// specifier += " volatile ";
|
|
|
|
if (specifier.length())
|
|
signature += " [" + specifier.simplified() + "]";
|
|
|
|
return signature;
|
|
// return role(Type) + " " + role(Name);
|
|
}
|
|
|
|
case Function: {
|
|
QByteArray signature, qualifier, ret = role(Return);
|
|
|
|
if (ret.length())
|
|
signature += ret + " ";
|
|
|
|
signature += role(Name);
|
|
|
|
signature += "(";
|
|
signature += role(Arguments);
|
|
signature += ")";
|
|
|
|
int m_qualifiers = role(Qualifiers).toInt();
|
|
|
|
if (m_qualifiers & QCodeNode::QUALIFIER_CONST)
|
|
qualifier += " const ";
|
|
// else if (m_qualifiers & QCodeNode::QUALIFIER_VOLATILE)
|
|
// qualifier += " volatile ";
|
|
// else if (m_qualifiers & QCodeNode::QUALIFIER_STATIC)
|
|
// qualifier += " static ";
|
|
|
|
/* if (m_qualifiers & QCodeNode::QUALIFIER_PURE_VIRTUAL)
|
|
qualifier.prepend(" pure virtual ");
|
|
else */
|
|
if (m_qualifiers & QCodeNode::QUALIFIER_INLINE)
|
|
qualifier.prepend(" inline ");
|
|
// else if (m_qualifiers & QCodeNode::QUALIFIER_VIRTUAL)
|
|
// qualifier.prepend(" virtual ");
|
|
|
|
int m_visibility = role(Visibility).toInt();
|
|
|
|
if (m_visibility == QCodeNode::VISIBILITY_PUBLIC)
|
|
qualifier.prepend(" public ");
|
|
else if (m_visibility == QCodeNode::VISIBILITY_PROTECTED)
|
|
qualifier.prepend(" protected ");
|
|
// else if (m_visibility == QCodeNode::VISIBILITY_SIGNAL)
|
|
// qualifier.prepend(" signal ");
|
|
else if (m_visibility == QCodeNode::VISIBILITY_PRIVATE)
|
|
qualifier.prepend(" private ");
|
|
else
|
|
qualifier.prepend(" global ");
|
|
|
|
if (ret.isEmpty()) {
|
|
if (role(Name).startsWith("~"))
|
|
qualifier += " destructor ";
|
|
else
|
|
qualifier += " constructor ";
|
|
}
|
|
|
|
if (qualifier.length())
|
|
signature += " [" + qualifier.simplified() + "]";
|
|
|
|
// return role(Name) + " " + role(Name);
|
|
return signature;
|
|
}
|
|
|
|
default:
|
|
break;
|
|
};
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
case Qt::DecorationRole: {
|
|
switch (t) {
|
|
case Class:
|
|
return icon(ICON_CLASS);
|
|
|
|
// case Struct:
|
|
// return icon(ICON_STRUCT);
|
|
|
|
case Enum:
|
|
return icon(ICON_ENUM);
|
|
|
|
case Enumerator:
|
|
return icon(ICON_ENUMERATOR);
|
|
|
|
// case Union:
|
|
// return icon(ICON_UNION);
|
|
|
|
case Namespace:
|
|
return icon(ICON_NAMESPACE);
|
|
|
|
case Typedef:
|
|
return icon(ICON_TYPEDEF);
|
|
|
|
case Variable:
|
|
return icon(ICON_VARIABLE + role(Visibility).toInt());
|
|
|
|
case Function:
|
|
return icon(ICON_FUNCTION + role(Visibility).toInt());
|
|
|
|
default:
|
|
break;
|
|
};
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return QVariant();
|
|
}
|
|
|
|
QByteArray QCodeNode::role(RoleIndex r) const { return roles.value(r); }
|
|
|
|
void QCodeNode::setRole(RoleIndex r, const QByteArray &b) { roles[r] = b; }
|
|
|
|
void QCodeNode::setNodeType(DefaultNodeTypes t) {
|
|
setRole(NodeType, QByteArray(1, t));
|
|
}
|