• Skip to content
  • Skip to link menu
KDE 4.4 API Reference
  • KDE API Reference
  • KDevelop Platform Libraries
  • Sitemap
  • Contact Us
 

language/duchain

abstractdeclarationnavigationcontext.cpp

00001 /*
00002    Copyright 2007 David Nolden <david.nolden.kdevelop@art-master.de>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License version 2 as published by the Free Software Foundation.
00007 
00008    This library is distributed in the hope that it will be useful,
00009    but WITHOUT ANY WARRANTY; without even the implied warranty of
00010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011    Library General Public License for more details.
00012 
00013    You should have received a copy of the GNU Library General Public License
00014    along with this library; see the file COPYING.LIB.  If not, write to
00015    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00016    Boston, MA 02110-1301, USA.
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   //Jump from definition to declaration if possible
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         //Do not show the own name as type of typedefs
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     //modifyHtml() += "<br />";
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() += " "; //The action name _must_ stay "show_uses", since that is also used from outside
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) /*+ "<br />"*/;
00264       }
00265     } else if(!comment.isEmpty()) {
00266       comment.replace("<br />", "\n"); //do not escape html newlines within the comment
00267       comment.replace("<br/>", "\n");
00268       comment = Qt::escape(comment);
00269       comment.replace('\n', "<br />"); //Replicate newlines in html
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     //modifyHtml() += "<br />";
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       //Check if this declarations hides other declarations
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     //Remove the last template-identifiers, because we create those directly
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       //Also create full type-links for the context around
00515       AbstractType::Ptr contextType = decl->context()->owner()->abstractType();
00516       IdentifiedType* contextIdType = dynamic_cast<IdentifiedType*>(contextType.unsafeData());
00517       if(contextIdType) {
00518         //Create full type information for the context
00519         if(!id.isEmpty())
00520           id = id.mid(id.count()-1);
00521         htmlIdentifiedType(contextType, contextIdType);
00522         modifyHtml() += Qt::escape("::");
00523       }
00524     }
00525 
00526     //We leave out the * and & reference and pointer signs, those are added to the end
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     //We need to exchange the target type, else template-parameters may confuse this
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 }

language/duchain

Skip menu "language/duchain"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

KDevelop Platform Libraries

Skip menu "KDevelop Platform Libraries"
  • interfaces
  • language
  •   codegen
  •   duchain
  •   editor
  • outputview
  • project
  • shell
  • sublime
  • util
  • vcs
Generated for KDevelop Platform Libraries by doxygen 1.5.9-20090814
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal