mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 03:12:53 +00:00
183 lines
6.2 KiB
C++
183 lines
6.2 KiB
C++
![]() |
/* This file is part of KDevelop
|
||
|
Copyright 2002-2005 Roberto Raggi <roberto@kdevelop.org>
|
||
|
Copyright 2006 Hamish Rodda <rodda@kde.org>
|
||
|
Copyright 2010 Milian Wolff <mail@milianw.de>
|
||
|
|
||
|
This library is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU Library General Public
|
||
|
License version 2 as published by the Free Software Foundation.
|
||
|
|
||
|
This library is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||
|
Library General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU Library General Public License
|
||
|
along with this library; see the file COPYING.LIB. If not, write to
|
||
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||
|
Boston, MA 02110-1301, USA.
|
||
|
*/
|
||
|
|
||
|
#include "dumpchain.h"
|
||
|
|
||
|
#include <QtCore/QString>
|
||
|
#include <QTextStream>
|
||
|
|
||
|
#include <KDebug>
|
||
|
|
||
|
#include "ducontext.h"
|
||
|
#include "topducontext.h"
|
||
|
#include "declaration.h"
|
||
|
#include "duchainpointer.h"
|
||
|
#include "identifier.h"
|
||
|
#include "use.h"
|
||
|
#include "problem.h"
|
||
|
#include "indexedstring.h"
|
||
|
#include "functiondefinition.h"
|
||
|
|
||
|
#include <editor/rangeinrevision.h>
|
||
|
|
||
|
using namespace KDevelop;
|
||
|
|
||
|
//BEGIN: private
|
||
|
|
||
|
class DumpChain
|
||
|
{
|
||
|
public:
|
||
|
DumpChain();
|
||
|
~DumpChain();
|
||
|
|
||
|
void dump( DUContext * context, int allowedDepth );
|
||
|
|
||
|
private:
|
||
|
int indent;
|
||
|
TopDUContext* top;
|
||
|
QSet<DUContext*> had;
|
||
|
};
|
||
|
|
||
|
DumpChain::DumpChain()
|
||
|
: indent(0), top(0)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
DumpChain::~DumpChain( )
|
||
|
{
|
||
|
}
|
||
|
|
||
|
class Indent {
|
||
|
private:
|
||
|
int m_level;
|
||
|
public:
|
||
|
Indent(int level): m_level(level) {}
|
||
|
friend QDebug& operator<<(QDebug& debug, const Indent& ind) {
|
||
|
for (int i=0; i<ind.m_level; i++) {
|
||
|
debug << ' ';
|
||
|
}
|
||
|
return debug;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
void DumpChain::dump( DUContext * context, int allowedDepth )
|
||
|
{
|
||
|
QTextStream globalOut(stdout);
|
||
|
// use a QDebug to utilize operator<<() overloads
|
||
|
// but don't use kDebug() to make sure we always print it, no matter what
|
||
|
// is set in kdebugdialog
|
||
|
QDebug qout(globalOut.device());
|
||
|
|
||
|
if(!top || top != context->topContext()) {
|
||
|
top = context->topContext();
|
||
|
if (!top->problems().isEmpty()) {
|
||
|
qout << "PROBLEMS:" << endl;
|
||
|
foreach(const ProblemPointer& p, top->problems()) {
|
||
|
qout << p->description() << p->explanation() << p->finalLocation().textRange() << endl;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
enum ContextType {
|
||
|
Global /**< A context that declares functions, namespaces or classes */,
|
||
|
Namespace /**< A context that declares namespace members */,
|
||
|
Class /**< A context that declares class members */,
|
||
|
Function /**< A context that declares function-arguments */,
|
||
|
Template /**< A context that declares template-parameters */,
|
||
|
Enum /**< A context that contains a list of enumerators */,
|
||
|
Helper /**< A helper context, used for language-specific tweaks */,
|
||
|
Other /**< Represents executable code, like for example within a compound-statement */
|
||
|
};
|
||
|
|
||
|
QString type;
|
||
|
switch(context->type()) {
|
||
|
case DUContext::Global: type = "Global"; break;
|
||
|
case DUContext::Namespace: type = "Namespace"; break;
|
||
|
case DUContext::Class: type = "Class"; break;
|
||
|
case DUContext::Function: type = "Function"; break;
|
||
|
case DUContext::Template: type = "Template"; break;
|
||
|
case DUContext::Enum: type = "Enum"; break;
|
||
|
case DUContext::Helper: type = "Helper"; break;
|
||
|
case DUContext::Other: type = "Other"; break;
|
||
|
}
|
||
|
qout << QString(indent * 2, ' ') << (indent ? "==import==> Context " : "New Context ") << type << context << "\"" << context->localScopeIdentifier() << "\" [" << context->scopeIdentifier() << "]" << context->range().castToSimpleRange().textRange() << ' ' << (dynamic_cast<TopDUContext*>(context) ? "top-context" : "") << endl;
|
||
|
|
||
|
|
||
|
if( !context )
|
||
|
return;
|
||
|
if (allowedDepth >= 0) {
|
||
|
foreach (Declaration* dec, context->localDeclarations(top)) {
|
||
|
|
||
|
//IdentifiedType* idType = dynamic_cast<IdentifiedType*>(dec->abstractType().data());
|
||
|
|
||
|
qout << QString((indent+1) * 2, ' ') << "Declaration: " << dec->toString() << /*(idType ? (" (type-identity: " + idType->identifier().toString() + ")") : QString()) <<*/ " [" << dec->qualifiedIdentifier() << "]" << dec << "(internal ctx" << dec->internalContext() << ")" << dec->range().castToSimpleRange().textRange() << "," << (dec->isDefinition() ? "defined, " : (FunctionDefinition::definition(dec) ? "" : "no definition, ")) << dec->uses().count() << "use(s)." << endl;
|
||
|
if (FunctionDefinition::definition(dec)) {
|
||
|
qout << QString((indent+1) * 2 + 1, ' ') << "Definition:" << FunctionDefinition::definition(dec)->range().castToSimpleRange().textRange() << endl;
|
||
|
}
|
||
|
QMap<IndexedString, QList<RangeInRevision> > uses = dec->uses();
|
||
|
for(QMap<IndexedString, QList<RangeInRevision> >::const_iterator it = uses.constBegin(); it != uses.constEnd(); ++it) {
|
||
|
qout << QString((indent+2) * 2, ' ') << "File:" << it.key().str() << endl;
|
||
|
foreach (const RangeInRevision& range, *it)
|
||
|
qout << QString((indent+2) * 2+1, ' ') << "Use:" << range.castToSimpleRange().textRange() << endl;
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
qout << QString((indent+1) * 2, ' ') << context->localDeclarations(top).count() << "Declarations, " << context->childContexts().size() << "child-contexts" << endl;
|
||
|
}
|
||
|
|
||
|
++indent;
|
||
|
{
|
||
|
foreach (const DUContext::Import &parent, context->importedParentContexts()) {
|
||
|
DUContext* import = parent.context(top);
|
||
|
if(!import) {
|
||
|
qout << QString((indent+2) * 2+1, ' ') << "Could not get parent, is it registered in the DUChain?" << endl;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if(had.contains(import)) {
|
||
|
qout << QString((indent+2) * 2+1, ' ') << "skipping" << import->scopeIdentifier(true) << "because it was already printed" << endl;
|
||
|
continue;
|
||
|
}
|
||
|
had.insert(import);
|
||
|
|
||
|
dump(import, allowedDepth-1);
|
||
|
}
|
||
|
|
||
|
foreach (DUContext* child, context->childContexts())
|
||
|
dump(child, allowedDepth-1);
|
||
|
}
|
||
|
--indent;
|
||
|
|
||
|
if(indent == 0) {
|
||
|
top = 0;
|
||
|
had.clear();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//END: private
|
||
|
|
||
|
//BEGIN: public
|
||
|
|
||
|
void KDevelop::dumpDUContext(DUContext* context, int allowedDepth)
|
||
|
{
|
||
|
DumpChain dumper;
|
||
|
dumper.dump(context, allowedDepth);
|
||
|
}
|