language/duchain
abstractincludenavigationcontext.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "abstractincludenavigationcontext.h"
00020
00021 #include <QtGui/QTextDocument>
00022
00023 #include <klocale.h>
00024
00025 #include <language/duchain/duchain.h>
00026 #include <language/duchain/parsingenvironment.h>
00027 #include <language/duchain/declaration.h>
00028
00029 namespace KDevelop {
00030
00031 AbstractIncludeNavigationContext::AbstractIncludeNavigationContext(const IncludeItem& item,
00032 TopDUContextPointer topContext,
00033 const ParsingEnvironmentType& type)
00034 : AbstractNavigationContext(topContext), m_type(type), m_item(item)
00035 {}
00036
00037 TopDUContext* pickContextWithData(QList<TopDUContext*> duchains, uint maxDepth,
00038 const ParsingEnvironmentType& type,
00039 bool forcePick = true) {
00040 TopDUContext* duchain = 0;
00041
00042 foreach(TopDUContext* ctx, duchains) {
00043 if(!ctx->parsingEnvironmentFile() || ctx->parsingEnvironmentFile()->type() != type)
00044 continue;
00045
00046 if(ctx->childContexts().count() != 0
00047 && (duchain == 0 || ctx->childContexts().count() > duchain->childContexts().count())) {
00048 duchain = ctx;
00049 }
00050 if(ctx->localDeclarations().count() != 0
00051 && (duchain == 0 || ctx->localDeclarations().count() > duchain->localDeclarations().count())) {
00052 duchain = ctx;
00053 }
00054 }
00055
00056 if(!duchain && maxDepth != 0) {
00057 if(maxDepth != 0) {
00058 foreach(TopDUContext* ctx, duchains) {
00059 QList<TopDUContext*> children;
00060 foreach(const DUContext::Import &import, ctx->importedParentContexts())
00061 if(import.context(0))
00062 children << import.context(0)->topContext();
00063
00064 duchain = pickContextWithData(children, maxDepth-1, type, false);
00065 if(duchain)
00066 break;
00067 }
00068 }
00069 }
00070
00071 if(!duchain && !duchains.isEmpty() && forcePick)
00072 duchain = duchains.first();
00073
00074 return duchain;
00075 }
00076
00077 QString AbstractIncludeNavigationContext::html(bool shorten)
00078 {
00079 clear();
00080 modifyHtml() += "<html><body><p><small><small>";
00081 addExternalHtml(m_prefix);
00082
00083 KUrl u(m_item.url());
00084 NavigationAction action(u, KTextEditor::Cursor(0,0));
00085 makeLink(u.fileName(), u.pathOrUrl(), action);
00086 QList<TopDUContext*> duchains = DUChain::self()->chainsForDocument(u);
00087 modifyHtml() += "<br />";
00088 modifyHtml() += "path: " + u.pathOrUrl();
00089
00090
00091
00092 TopDUContext* duchain = pickContextWithData(duchains, 2, m_type);
00093
00094 modifyHtml() += "<br />";
00095
00096 if(duchain) {
00097 getFileInfo(duchain);
00098 if(!shorten) {
00099 modifyHtml() += labelHighlight(i18n("Declarations:")) + "<br />";
00100 bool first = true;
00101 addDeclarationsFromContext(duchain, first);
00102 }
00103 }else if(duchains.isEmpty()) {
00104 modifyHtml() += i18n("not parsed yet");
00105 }
00106
00107 addExternalHtml(m_suffix);
00108
00109 modifyHtml() += "</small></small></p></body></html>";
00110 return currentHtml();
00111 }
00112
00113 void AbstractIncludeNavigationContext::getFileInfo(TopDUContext* duchain)
00114 {
00115 modifyHtml() += QString("%1: %2 %3: %4").arg(labelHighlight(i18nc("Files included into this file", "Includes"))).arg(duchain->importedParentContexts().count()).arg(i18nc("Count of files this file was included into", "Included by")).arg(duchain->importers().count());
00116 modifyHtml() += "<br />";
00117 }
00118
00119 QString AbstractIncludeNavigationContext::name() const
00120 {
00121 return m_item.name;
00122 }
00123
00124 void AbstractIncludeNavigationContext::addDeclarationsFromContext(KDevelop::DUContext* ctx, bool& first, QString indent)
00125 {
00126
00127 QVector<DUContext*> children = ctx->childContexts();
00128 QVector<Declaration*> declarations = ctx->localDeclarations();
00129
00130 QVector<DUContext*>::const_iterator childIterator = children.constBegin();
00131 QVector<Declaration*>::const_iterator declarationIterator = declarations.constBegin();
00132
00133 while(childIterator != children.constEnd() || declarationIterator != declarations.constEnd()) {
00134
00135
00136 int currentDeclarationLine = -1;
00137 int currentContextLine = -1;
00138 if(declarationIterator != declarations.constEnd())
00139 currentDeclarationLine = (*declarationIterator)->range().textRange().start().line();
00140
00141 if(childIterator != children.constEnd())
00142 currentDeclarationLine = (*childIterator)->range().textRange().start().line();
00143
00144 if((currentDeclarationLine <= currentContextLine || currentContextLine == -1 || childIterator == children.constEnd()) && declarationIterator != declarations.constEnd() )
00145 {
00146 if(!(*declarationIterator)->qualifiedIdentifier().toString().isEmpty() && !(*declarationIterator)->range().isEmpty() && !(*declarationIterator)->isForwardDeclaration()) {
00147
00148 if(!first)
00149 modifyHtml() += Qt::escape(", ");
00150 else
00151 first = false;
00152
00153 modifyHtml() += Qt::escape(indent + declarationKind(DeclarationPointer(*declarationIterator)) + " ");
00154 makeLink((*declarationIterator)->qualifiedIdentifier().toString(), DeclarationPointer(*declarationIterator), NavigationAction::NavigateDeclaration);
00155 }
00156 ++declarationIterator;
00157 } else {
00158
00159 if((*childIterator)->type() == DUContext::Global || (*childIterator)->type() == DUContext::Namespace )
00160 addDeclarationsFromContext(*childIterator, first, indent + ' ');
00161 ++childIterator;
00162 }
00163 }
00164
00165 }
00166
00167 }