00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "abstractdeclarationnavigationcontext.h"
00020
00021 #include <QtGui/QTextDocument>
00022
00023 #include <klocale.h>
00024
00025 #include "../functiondeclaration.h"
00026 #include "../functiondefinition.h"
00027 #include "../classfunctiondeclaration.h"
00028 #include "../namespacealiasdeclaration.h"
00029 #include "../forwarddeclaration.h"
00030 #include "../types/enumeratortype.h"
00031 #include "../types/enumerationtype.h"
00032 #include "../types/functiontype.h"
00033 #include "../duchainutils.h"
00034 #include "../types/pointertype.h"
00035 #include "../types/referencetype.h"
00036 #include "../types/typeutils.h"
00037 #include "../persistentsymboltable.h"
00038 #include <interfaces/icore.h>
00039 #include <interfaces/idocumentationcontroller.h>
00040 #include <duchain/types/typealiastype.h>
00041 #include <duchain/classdeclaration.h>
00042 #include <typeinfo>
00043
00044 namespace KDevelop {
00045 AbstractDeclarationNavigationContext::AbstractDeclarationNavigationContext( DeclarationPointer decl, KDevelop::TopDUContextPointer topContext, AbstractNavigationContext* previousContext)
00046 : AbstractNavigationContext((topContext ? topContext : TopDUContextPointer(decl ? decl->topContext() : 0)), previousContext), m_declaration(decl), m_fullBackwardSearch(false)
00047 {
00048
00049 FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(m_declaration.data());
00050 if(definition && definition->declaration())
00051 m_declaration = DeclarationPointer(definition->declaration());
00052 }
00053
00054 QString AbstractDeclarationNavigationContext::name() const
00055 {
00056 if(m_declaration.data())
00057 return prettyQualifiedIdentifier(m_declaration).toString();
00058 else
00059 return declarationName(m_declaration);
00060 }
00061
00062 QString AbstractDeclarationNavigationContext::html(bool shorten)
00063 {
00064 clear();
00065 m_shorten = shorten;
00066 modifyHtml() += "<html><body><p><small><small>";
00067
00068 addExternalHtml(m_prefix);
00069
00070 if(!m_declaration.data()) {
00071 modifyHtml() += i18n("<br /> lost declaration <br />");
00072 return currentHtml();
00073 }
00074
00075 if( m_previousContext ) {
00076 modifyHtml() += navigationHighlight("Back to ");
00077 makeLink( m_previousContext->name(), m_previousContext->name(), NavigationAction(m_previousContext) );
00078 modifyHtml() += "<br>";
00079 }
00080
00081 KSharedPtr<IDocumentation> doc;
00082
00083 if( !shorten ) {
00084 doc = ICore::self()->documentationController()->documentationForDeclaration(m_declaration.data());
00085
00086 const AbstractFunctionDeclaration* function = dynamic_cast<const AbstractFunctionDeclaration*>(m_declaration.data());
00087 if( function ) {
00088 htmlFunction();
00089 } else if( m_declaration->isTypeAlias() || m_declaration->kind() == Declaration::Instance ) {
00090 if( m_declaration->isTypeAlias() )
00091 modifyHtml() += importantHighlight("typedef ");
00092
00093 if(m_declaration->type<EnumeratorType>())
00094 modifyHtml() += i18n("enumerator ");
00095
00096 AbstractType::Ptr useType = m_declaration->abstractType();
00097 if(m_declaration->isTypeAlias()) {
00098
00099 if(useType.cast<TypeAliasType>())
00100 useType = useType.cast<TypeAliasType>()->type();
00101 }
00102
00103 eventuallyMakeTypeLinks( useType );
00104
00105 modifyHtml() += ' ' + nameHighlight(Qt::escape(declarationName(m_declaration))) + "<br>";
00106 }else{
00107 if( m_declaration->kind() == Declaration::Type && m_declaration->abstractType().cast<StructureType>() ) {
00108 htmlClass();
00109 }
00110
00111 if(m_declaration->type<EnumerationType>()) {
00112 EnumerationType::Ptr enumeration = m_declaration->type<EnumerationType>();
00113 modifyHtml() += i18n("enumeration %1 <br/>", Qt::escape(m_declaration->identifier().toString()) );
00114 }
00115
00116 if(m_declaration->isForwardDeclaration()) {
00117 ForwardDeclaration* forwardDec = static_cast<ForwardDeclaration*>(m_declaration.data());
00118 Declaration* resolved = forwardDec->resolve(m_topContext.data());
00119 if(resolved) {
00120 modifyHtml() += i18n("( resolved forward-declaration: ");
00121 makeLink(resolved->identifier().toString(), KDevelop::DeclarationPointer(resolved), NavigationAction::NavigateDeclaration );
00122 modifyHtml() += i18n(") ");
00123 }else{
00124 modifyHtml() += i18n("(unresolved forward-declaration) ");
00125 QualifiedIdentifier id = forwardDec->qualifiedIdentifier();
00126 uint count;
00127 const IndexedDeclaration* decls;
00128 PersistentSymbolTable::self().declarations(id, count, decls);
00129 bool had = false;
00130 for(uint a = 0; a < count; ++a) {
00131 if(decls[a].isValid() && !decls[a].data()->isForwardDeclaration()) {
00132 modifyHtml() += "<br />";
00133 makeLink(i18n("possible resolution from"), KDevelop::DeclarationPointer(decls[a].data()), NavigationAction::NavigateDeclaration);
00134 modifyHtml() += ' ' + decls[a].data()->url().str();
00135 had = true;
00136 }
00137 }
00138 if(had)
00139 modifyHtml() += "<br />";
00140 }
00141 }
00142 }
00143 }else{
00144 AbstractType::Ptr showType = m_declaration->abstractType();
00145 if(showType && showType.cast<FunctionType>()) {
00146 showType = showType.cast<FunctionType>()->returnType();
00147 if(showType)
00148 modifyHtml() += labelHighlight(i18n("Returns: "));
00149 }else if(showType) {
00150 modifyHtml() += labelHighlight(i18n("Type: "));
00151 }
00152
00153 if(showType) {
00154 eventuallyMakeTypeLinks(showType);
00155 modifyHtml() += " ";
00156 }
00157 }
00158
00159 QualifiedIdentifier identifier = m_declaration->qualifiedIdentifier();
00160 if( identifier.count() > 1 ) {
00161 if( m_declaration->context() && m_declaration->context()->owner() )
00162 {
00163 Declaration* decl = m_declaration->context()->owner();
00164
00165 FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(decl);
00166 if(definition && definition->declaration())
00167 decl = definition->declaration();
00168
00169 if(decl->abstractType().cast<EnumerationType>())
00170 modifyHtml() += labelHighlight(i18n("Enum: "));
00171 else
00172 modifyHtml() += labelHighlight(i18n("Container: "));
00173
00174 makeLink( declarationName(DeclarationPointer(decl)), DeclarationPointer(decl), NavigationAction::NavigateDeclaration );
00175 modifyHtml() += " ";
00176 } else {
00177 QualifiedIdentifier parent = identifier;
00178 parent.pop();
00179 modifyHtml() += labelHighlight(i18n("Scope: %1 ", typeHighlight(Qt::escape(parent.toString()))));
00180 }
00181 }
00182
00183 if( shorten && !m_declaration->comment().isEmpty() ) {
00184 QString comment = QString::fromUtf8(m_declaration->comment());
00185 if( comment.length() > 60 ) {
00186 comment.truncate(60);
00187 comment += "...";
00188 }
00189 comment.replace('\n', " ");
00190 comment.replace("<br />", " ");
00191 comment.replace("<br/>", " ");
00192 modifyHtml() += commentHighlight(Qt::escape(comment)) + " ";
00193 }
00194
00195
00196 QString access = stringFromAccess(m_declaration);
00197 if( !access.isEmpty() )
00198 modifyHtml() += labelHighlight(i18n("Access: %1 ", propertyHighlight(Qt::escape(access))));
00199
00200
00202
00203 QString detailsHtml;
00204 QStringList details = declarationDetails(m_declaration);
00205 if( !details.isEmpty() ) {
00206 bool first = true;
00207 foreach( const QString &str, details ) {
00208 if( !first )
00209 detailsHtml += ", ";
00210 first = false;
00211 detailsHtml += propertyHighlight(str);
00212 }
00213 }
00214
00215 QString kind = declarationKind(m_declaration);
00216 if( !kind.isEmpty() ) {
00217 if( !detailsHtml.isEmpty() )
00218 modifyHtml() += labelHighlight(i18n("Kind: %1 %2 ", importantHighlight(Qt::escape(kind)), detailsHtml));
00219 else
00220 modifyHtml() += labelHighlight(i18n("Kind: %1 ", importantHighlight(Qt::escape(kind))));
00221 } else if( !detailsHtml.isEmpty() ) {
00222 modifyHtml() += labelHighlight(i18n("Modifiers: %1 ", importantHighlight(Qt::escape(kind))));
00223 }
00224
00225 modifyHtml() += "<br />";
00226
00227 if(!shorten)
00228 htmlAdditionalNavigation();
00229
00230 if( !shorten ) {
00231 if(dynamic_cast<FunctionDefinition*>(m_declaration.data()))
00232 modifyHtml() += labelHighlight(i18n( "Def.: " ));
00233 else
00234 modifyHtml() += labelHighlight(i18n( "Decl.: " ));
00235
00236 makeLink( QString("%1 :%2").arg( KUrl(m_declaration->url().str()).fileName() ).arg( m_declaration->range().textRange().start().line()+1 ), m_declaration, NavigationAction::JumpToSource );
00237 modifyHtml() += " ";
00238
00239 if(!dynamic_cast<FunctionDefinition*>(m_declaration.data())) {
00240 if( FunctionDefinition* definition = FunctionDefinition::definition(m_declaration.data()) ) {
00241 modifyHtml() += labelHighlight(i18n( " Def.: " ));
00242 makeLink( QString("%1 :%2").arg( KUrl(definition->url().str()).fileName() ).arg( definition->range().textRange().start().line()+1 ), DeclarationPointer(definition), NavigationAction::JumpToSource );
00243 }
00244 }
00245
00246 if( FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(m_declaration.data()) ) {
00247 if(definition->declaration()) {
00248 modifyHtml() += labelHighlight(i18n( " Decl.: " ));
00249 makeLink( QString("%1 :%2").arg( KUrl(definition->declaration()->url().str()).fileName() ).arg( definition->declaration()->range().textRange().start().line()+1 ), DeclarationPointer(definition->declaration()), NavigationAction::JumpToSource );
00250 }
00251 }
00252
00253 modifyHtml() += " ";
00254 makeLink(i18n("Show uses"), "show_uses", NavigationAction(m_declaration, NavigationAction::NavigateUses));
00255 }
00256
00257 if( !shorten && (!m_declaration->comment().isEmpty() || doc) ) {
00258 modifyHtml() += "<br />";
00259 QString comment = QString::fromUtf8(m_declaration->comment());
00260 if(comment.isEmpty() && doc) {
00261 comment = doc->description();
00262 if(!comment.isEmpty()) {
00263 modifyHtml() += commentHighlight(comment) ;
00264 }
00265 } else if(!comment.isEmpty()) {
00266 comment.replace("<br />", "\n");
00267 comment.replace("<br/>", "\n");
00268 comment = Qt::escape(comment);
00269 comment.replace('\n', "<br />");
00270 modifyHtml() += commentHighlight(comment);
00271 modifyHtml() += "<br />";
00272 }
00273 }
00274
00275 if(!shorten && doc) {
00276 modifyHtml() += "<br />" + i18n("Show documentation for ");
00277 makeLink( prettyQualifiedIdentifier(m_declaration).toString(), m_declaration, NavigationAction::ShowDocumentation );
00278 }
00279
00280
00281
00282
00283 addExternalHtml(m_suffix);
00284
00285 modifyHtml() += "</small></small></p></body></html>";
00286
00287 return currentHtml();
00288 }
00289
00290 KDevelop::AbstractType::Ptr AbstractDeclarationNavigationContext::typeToShow(KDevelop::AbstractType::Ptr type) {
00291 return type;
00292 }
00293
00294 void AbstractDeclarationNavigationContext::htmlFunction()
00295 {
00296 const AbstractFunctionDeclaration* function = dynamic_cast<const AbstractFunctionDeclaration*>(m_declaration.data());
00297 Q_ASSERT(function);
00298
00299 const ClassFunctionDeclaration* classFunDecl = dynamic_cast<const ClassFunctionDeclaration*>(m_declaration.data());
00300 const FunctionType::Ptr type = m_declaration->abstractType().cast<FunctionType>();
00301 if( !type ) {
00302 modifyHtml() += errorHighlight("Invalid type<br />");
00303 return;
00304 }
00305 if( !classFunDecl || !classFunDecl->isConstructor() || !classFunDecl->isDestructor() ) {
00306 eventuallyMakeTypeLinks( type->returnType() );
00307 modifyHtml() += ' ' + nameHighlight(Qt::escape(prettyIdentifier(m_declaration).toString()));
00308 }
00309
00310 if( type->arguments().count() == 0 )
00311 {
00312 modifyHtml() += "()";
00313 } else {
00314 modifyHtml() += "( ";
00315 bool first = true;
00316
00317 KDevelop::DUContext* argumentContext = DUChainUtils::getArgumentContext(m_declaration.data());
00318
00319 if(argumentContext) {
00320 int firstDefaultParam = argumentContext->localDeclarations(m_topContext.data()).count() - function->defaultParametersSize();
00321 int currentArgNum = 0;
00322
00323 foreach(Declaration* argument, argumentContext->localDeclarations(m_topContext.data())) {
00324 if( !first )
00325 modifyHtml() += ", ";
00326 first = false;
00327
00328 AbstractType::Ptr argType = argument->abstractType();
00329
00330 eventuallyMakeTypeLinks( argType );
00331 modifyHtml() += ' ' + nameHighlight(Qt::escape(argument->identifier().toString()));
00332
00333 if( currentArgNum >= firstDefaultParam )
00334 modifyHtml() += " = " + Qt::escape(function->defaultParameters()[ currentArgNum - firstDefaultParam ].str());
00335
00336 ++currentArgNum;
00337 }
00338 }
00339
00340 modifyHtml() += " )";
00341 }
00342 modifyHtml() += "<br />";
00343 }
00344
00345
00346 Identifier AbstractDeclarationNavigationContext::prettyIdentifier(DeclarationPointer decl) const
00347 {
00348 Identifier ret;
00349 QualifiedIdentifier q = prettyQualifiedIdentifier(decl);
00350 if(!q.isEmpty())
00351 ret = q.last();
00352
00353 return ret;
00354 }
00355
00356 QualifiedIdentifier AbstractDeclarationNavigationContext::prettyQualifiedIdentifier(DeclarationPointer decl) const
00357 {
00358 if(decl)
00359 return decl->qualifiedIdentifier();
00360 else
00361 return QualifiedIdentifier();
00362 }
00363
00364 void AbstractDeclarationNavigationContext::htmlAdditionalNavigation()
00365 {
00367 const ClassFunctionDeclaration* classFunDecl = dynamic_cast<const ClassFunctionDeclaration*>(m_declaration.data());
00368 if(classFunDecl) {
00369
00370 Declaration* overridden = DUChainUtils::getOverridden(m_declaration.data());
00371
00372 if(overridden) {
00373 modifyHtml() += i18n("Overrides a ");
00374 makeLink(i18n("function"), QString("jump_to_overridden"), NavigationAction(DeclarationPointer(overridden), KDevelop::NavigationAction::NavigateDeclaration));
00375 modifyHtml() += i18n(" from ");
00376 makeLink(prettyQualifiedIdentifier(DeclarationPointer(overridden->context()->owner())).toString(), QString("jump_to_overridden_container"), NavigationAction(DeclarationPointer(overridden->context()->owner()), KDevelop::NavigationAction::NavigateDeclaration));
00377
00378 modifyHtml() += "<br />";
00379 }else{
00380
00381 QList<Declaration*> decls;
00382 foreach(const DUContext::Import &import, m_declaration->context()->importedParentContexts())
00383 if(import.context(m_topContext.data()))
00384 decls += import.context(m_topContext.data())->findDeclarations(QualifiedIdentifier(m_declaration->identifier()),
00385 SimpleCursor::invalid(), AbstractType::Ptr(), m_topContext.data(), DUContext::DontSearchInParent);
00386 uint num = 0;
00387 foreach(Declaration* decl, decls) {
00388 modifyHtml() += i18n("Hides a ");
00389 makeLink(i18n("function"), QString("jump_to_hide_%1").arg(num), NavigationAction(DeclarationPointer(decl), KDevelop::NavigationAction::NavigateDeclaration));
00390 modifyHtml() += i18n(" from ");
00391 makeLink(prettyQualifiedIdentifier(DeclarationPointer(decl->context()->owner())).toString(), QString("jump_to_hide_container_%1").arg(num), NavigationAction(DeclarationPointer(decl->context()->owner()), KDevelop::NavigationAction::NavigateDeclaration));
00392
00393 modifyHtml() += "<br />";
00394 ++num;
00395 }
00396 }
00397
00399 if(classFunDecl->isVirtual()) {
00400 Declaration* classDecl = m_declaration->context()->owner();
00401 if(classDecl) {
00402 uint maxAllowedSteps = m_fullBackwardSearch ? (uint)-1 : 10;
00403 QList<Declaration*> overriders = DUChainUtils::getOverriders(classDecl, classFunDecl, maxAllowedSteps);
00404
00405 if(!overriders.isEmpty()) {
00406 modifyHtml() += i18n("Overridden in ");
00407 bool first = true;
00408 foreach(Declaration* overrider, overriders) {
00409 if(!first)
00410 modifyHtml() += ", ";
00411 first = false;
00412
00413 QString name = prettyQualifiedIdentifier(DeclarationPointer(overrider->context()->owner())).toString();
00414 makeLink(name, name, NavigationAction(DeclarationPointer(overrider), NavigationAction::NavigateDeclaration));
00415 }
00416 modifyHtml() += "<br />";
00417 }
00418 if(maxAllowedSteps == 0)
00419 createFullBackwardSearchLink(overriders.isEmpty() ? i18n("Overriders possible, show all") : i18n("More overriders possible, show all"));
00420 }
00421 }
00422 }
00423
00425 uint maxAllowedSteps = m_fullBackwardSearch ? (uint)-1 : 10;
00426 QList<Declaration*> inheriters = DUChainUtils::getInheriters(m_declaration.data(), maxAllowedSteps);
00427
00428 if(!inheriters.isEmpty()) {
00429 modifyHtml() += i18n("Inherited by ");
00430 bool first = true;
00431 foreach(Declaration* importer, inheriters) {
00432 if(!first)
00433 modifyHtml() += ", ";
00434 first = false;
00435
00436 QString importerName = prettyQualifiedIdentifier(DeclarationPointer(importer)).toString();
00437 makeLink(importerName, importerName, NavigationAction(DeclarationPointer(importer), KDevelop::NavigationAction::NavigateDeclaration));
00438 }
00439 modifyHtml() += "<br />";
00440 }
00441 if(maxAllowedSteps == 0)
00442 createFullBackwardSearchLink(inheriters.isEmpty() ? i18n("Inheriters possible, show all") : i18n("More inheriters possible, show all"));
00443 }
00444
00445 void AbstractDeclarationNavigationContext::createFullBackwardSearchLink(QString string)
00446 {
00447 makeLink(string, "m_fullBackwardSearch=true", NavigationAction("m_fullBackwardSearch=true"));
00448 modifyHtml() += "<br />";
00449 }
00450
00451 NavigationContextPointer AbstractDeclarationNavigationContext::executeKeyAction( QString key )
00452 {
00453 if(key == "m_fullBackwardSearch=true") {
00454 m_fullBackwardSearch = true;
00455 clear();
00456 }
00457 return NavigationContextPointer(this);
00458 }
00459
00460 void AbstractDeclarationNavigationContext::htmlClass()
00461 {
00462 StructureType::Ptr klass = m_declaration->abstractType().cast<StructureType>();
00463 Q_ASSERT(klass);
00464
00465 ClassDeclaration* classDecl = dynamic_cast<ClassDeclaration*>(klass->declaration(m_topContext.data()));
00466 if(classDecl) {
00467 switch ( classDecl->classType() ) {
00468 case ClassDeclarationData::Class:
00469 modifyHtml() += "class ";
00470 break;
00471 case ClassDeclarationData::Struct:
00472 modifyHtml() += "struct ";
00473 break;
00474 case ClassDeclarationData::Union:
00475 modifyHtml() += "union ";
00476 break;
00477 case ClassDeclarationData::Interface:
00478 modifyHtml() += "interface ";
00479 break;
00480 default:
00481 modifyHtml() += "<unknown type> ";
00482 break;
00483 }
00484 eventuallyMakeTypeLinks( klass.cast<AbstractType>() );
00485
00486 FOREACH_FUNCTION( const KDevelop::BaseClassInstance& base, classDecl->baseClasses ) {
00487 modifyHtml() += ", " + stringFromAccess(base.access) + " " + (base.virtualInheritance ? QString("virtual") : QString()) + " ";
00488 eventuallyMakeTypeLinks(base.baseClass.abstractType());
00489 }
00490 modifyHtml() += " ";
00491 } else {
00493 modifyHtml() += "class ";
00494 eventuallyMakeTypeLinks( klass.cast<AbstractType>() );
00495 }
00496 }
00497
00498 void AbstractDeclarationNavigationContext::htmlIdentifiedType(AbstractType::Ptr type, const IdentifiedType* idType)
00499 {
00500 Q_ASSERT(type);
00501 Q_ASSERT(idType);
00502
00503 if( Declaration* decl = idType->declaration(m_topContext.data()) ) {
00504
00505
00506 QualifiedIdentifier id = prettyQualifiedIdentifier(DeclarationPointer(decl));
00507 Identifier lastId = id.last();
00508 id.pop();
00509 lastId.clearTemplateIdentifiers();
00510 id.push(lastId);
00511
00512 if(decl->context() && decl->context()->owner()) {
00513
00514
00515 AbstractType::Ptr contextType = decl->context()->owner()->abstractType();
00516 IdentifiedType* contextIdType = dynamic_cast<IdentifiedType*>(contextType.unsafeData());
00517 if(contextIdType) {
00518
00519 if(!id.isEmpty())
00520 id = id.mid(id.count()-1);
00521 htmlIdentifiedType(contextType, contextIdType);
00522 modifyHtml() += Qt::escape("::");
00523 }
00524 }
00525
00526
00527 makeLink(id.toString() , DeclarationPointer(idType->declaration(m_topContext.data())), NavigationAction::NavigateDeclaration );
00528 } else {
00529 kDebug() << "could not resolve declaration:" << idType->declarationId().isDirect() << idType->qualifiedIdentifier().toString() << "in top-context" << m_topContext->url().str();
00530 modifyHtml() += typeHighlight(Qt::escape(type->toString()));
00531 }
00532 }
00533
00534 void AbstractDeclarationNavigationContext::eventuallyMakeTypeLinks( AbstractType::Ptr type )
00535 {
00536 type = typeToShow(type);
00537
00538 if( !type ) {
00539 modifyHtml() += typeHighlight(Qt::escape("<no type>"));
00540 return;
00541 }
00542
00543 AbstractType::Ptr target = TypeUtils::targetTypeKeepAliases( type, m_topContext.data() );
00544 const IdentifiedType* idType = dynamic_cast<const IdentifiedType*>( target.unsafeData() );
00545
00546 kDebug() << "making type-links for" << type->toString() << typeid(*type).name();
00547
00548 if( idType && idType->declaration(m_topContext.data()) ) {
00550
00551 if(target->modifiers() & AbstractType::ConstModifier)
00552 modifyHtml() += typeHighlight("const ");
00553
00554 htmlIdentifiedType(target, idType);
00555
00556
00557 SimpleTypeExchanger exchangeTarget(target, AbstractType::Ptr());
00558
00559 AbstractType::Ptr exchanged = exchangeTarget.exchange(type);
00560
00561 if(exchanged) {
00562 QString typeSuffixString = exchanged->toString();
00563 QRegExp suffixExp("\\&|\\*");
00564 int suffixPos = typeSuffixString.indexOf(suffixExp);
00565 if(suffixPos != -1)
00566 modifyHtml() += typeHighlight(typeSuffixString.mid(suffixPos));
00567 }
00568
00569 } else {
00570 if(idType) {
00571 kDebug() << "identified type could not be resolved:" << idType->qualifiedIdentifier() << idType->declarationId().isValid() << idType->declarationId().isDirect();
00572 }
00573 modifyHtml() += typeHighlight(Qt::escape(type->toString()));
00574 }
00575 }
00576
00577 DeclarationPointer AbstractDeclarationNavigationContext::declaration() const
00578 {
00579 return m_declaration;
00580 }
00581
00582 QString AbstractDeclarationNavigationContext::stringFromAccess(Declaration::AccessPolicy access)
00583 {
00584 switch(access) {
00585 case Declaration::Private:
00586 return "private";
00587 case Declaration::Protected:
00588 return "protected";
00589 case Declaration::Public:
00590 return "public";
00591 }
00592 return "";
00593 }
00594
00595 QString AbstractDeclarationNavigationContext::stringFromAccess(DeclarationPointer decl)
00596 {
00597 const ClassMemberDeclaration* memberDecl = dynamic_cast<const ClassMemberDeclaration*>(decl.data());
00598 if( memberDecl ) {
00599 return stringFromAccess(memberDecl->accessPolicy());
00600 }
00601 return QString();
00602 }
00603
00604 QString AbstractDeclarationNavigationContext::declarationName( DeclarationPointer decl ) const
00605 {
00606 if( NamespaceAliasDeclaration* alias = dynamic_cast<NamespaceAliasDeclaration*>(decl.data()) ) {
00607 if( alias->identifier().isEmpty() )
00608 return "using namespace " + alias->importIdentifier().toString();
00609 else
00610 return "namespace " + alias->identifier().toString() + " = " + alias->importIdentifier().toString();
00611 }
00612
00613 if( !decl )
00614 return i18nc("A declaration that is unknown", "Unknown");
00615 else
00616 return prettyIdentifier(decl).toString();
00617 }
00618
00619 QStringList AbstractDeclarationNavigationContext::declarationDetails(DeclarationPointer decl)
00620 {
00621 QStringList details;
00622 const AbstractFunctionDeclaration* function = dynamic_cast<const AbstractFunctionDeclaration*>(decl.data());
00623 const ClassMemberDeclaration* memberDecl = dynamic_cast<const ClassMemberDeclaration*>(decl.data());
00624 if( memberDecl ) {
00625 if( memberDecl->isMutable() )
00626 details << "mutable";
00627 if( memberDecl->isRegister() )
00628 details << "register";
00629 if( memberDecl->isStatic() )
00630 details << "static";
00631 if( memberDecl->isAuto() )
00632 details << "auto";
00633 if( memberDecl->isExtern() )
00634 details << "extern";
00635 if( memberDecl->isFriend() )
00636 details << "friend";
00637 }
00638
00639 if( decl->isDefinition() )
00640 details << "definition";
00641
00642 if( memberDecl && memberDecl->isForwardDeclaration() )
00643 details << "forward";
00644
00645 AbstractType::Ptr t(decl->abstractType());
00646 if( t ) {
00647 if( t->modifiers() & AbstractType::ConstModifier )
00648 details << "constant";
00649 if( t->modifiers() & AbstractType::VolatileModifier )
00650 details << "volatile";
00651 }
00652 if( function ) {
00653
00654 if( function->isInline() )
00655 details << "inline";
00656
00657 if( function->isExplicit() )
00658 details << "explicit";
00659
00660 if( function->isVirtual() )
00661 details << "virtual";
00662
00663 const ClassFunctionDeclaration* classFunDecl = dynamic_cast<const ClassFunctionDeclaration*>(decl.data());
00664
00665 if( classFunDecl ) {
00666 if( classFunDecl->isSignal() )
00667 details << "signal";
00668 if( classFunDecl->isSlot() )
00669 details << "slot";
00670 if( classFunDecl->isConstructor() )
00671 details << "constructor";
00672 if( classFunDecl->isDestructor() )
00673 details << "destructor";
00674 if( classFunDecl->isConversionFunction() )
00675 details << "conversion-function";
00676 if( classFunDecl->isAbstract() )
00677 details << "abstract";
00678 }
00679 }
00680
00681 return details;
00682 }
00683
00684 }