void DeclarationBuilder::visitAliasStatement(Ast *node) { Ast *right = new Ast(node->tree->r, node->context); QualifiedIdentifier id = QualifiedIdentifier(QString(right->tree->name)); const RangeInRevision &range = editorFindRange(right, right); DeclarationPointer decl = getDeclaration(id, range, DUContextPointer(currentContext())); if (is_global_var(node->tree->l) && is_global_var(right->tree)) { DUChainWriteLocker wlock; // If the global variable on the right is not declared, declare it as nil if (!decl) { AbstractType::Ptr type = topContext()->findDeclarations(QualifiedIdentifier("NilClass")).first()->abstractType(); VariableDeclaration *vDecl = openDefinition<VariableDeclaration>(id, range); vDecl->setVariableKind(right->tree); vDecl->setKind(Declaration::Instance); vDecl->setType(type); eventuallyAssignInternalContext(); DeclarationBuilderBase::closeDeclaration(); decl = vDecl; } node->tree = node->tree->l; QualifiedIdentifier aid = getIdentifier(node); AbstractType::Ptr type = decl->abstractType(); declareVariable(aid, type, node); } else if (decl && decl->isFunctionDeclaration()) { DUChainWriteLocker wlock; MethodDeclaration *md = dynamic_cast<MethodDeclaration *>(decl.data()); node->tree = node->tree->l; const RangeInRevision & arange = editorFindRange(node, node); QualifiedIdentifier aid = getIdentifier(node); aliasMethodDeclaration(aid, arange, md); } else appendProblem(node->tree, i18n("undefined method `%1'", id.toString())); }
QPair<DUContext*, QualifiedIdentifier> ContextBuilder::findPrefixContext(const QualifiedIdentifier& id, KDevelop::SimpleCursor pos) { if(id.count() < 2) return qMakePair((DUContext*)0, QualifiedIdentifier()); QualifiedIdentifier prefixId(id); prefixId.pop(); DUContext* import = 0; { DUChainReadLocker lock(DUChain::lock()); QualifiedIdentifier currentScopeId = currentContext()->scopeIdentifier(true); QList<Declaration*> decls = currentContext()->findDeclarations(prefixId, pos); if(!decls.isEmpty()) { DUContext* classContext = decls.first()->logicalInternalContext(0); if(classContext && classContext->type() == DUContext::Class) { import = classContext; //Change the prefix-id so it respects namespace-imports prefixId = classContext->scopeIdentifier(true); if(prefixId.count() >= currentScopeId.count() && prefixId.left(currentScopeId.count()) == currentScopeId) prefixId = prefixId.mid(currentScopeId.count()); else kDebug() << "resolved bad prefix context. Should start with" << currentScopeId.toString() << "but is" << prefixId.toString(); } } } return qMakePair(import, prefixId); }
QList<QVariant> DUChainItemData::highlighting() const { DUChainReadLocker lock;; Declaration* decl = m_item.m_item.data(); if(!decl) { return QList<QVariant>(); } if(FunctionDefinition* def = dynamic_cast<FunctionDefinition*>(decl)) { if(def->declaration()) { decl = def->declaration(); } } QTextCharFormat boldFormat; boldFormat.setFontWeight(QFont::Bold); QTextCharFormat normalFormat; int prefixLength = 0; QString signature; TypePtr<FunctionType> function = decl->type<FunctionType>(); if(function) { signature = function->partToString( FunctionType::SignatureArguments ); } //Only highlight the last part of the qualified identifier, so the scope doesn't distract too much QualifiedIdentifier id = decl->qualifiedIdentifier(); QString fullId = id.toString(); QString lastId; if(!id.isEmpty()) { lastId = id.last().toString(); } prefixLength += fullId.length() - lastId.length(); QList<QVariant> ret; ret << 0; ret << prefixLength; ret << QVariant(normalFormat); ret << prefixLength; ret << lastId.length(); ret << QVariant(boldFormat); if(!signature.isEmpty()) { ret << prefixLength + lastId.length(); ret << signature.length(); ret << QVariant(normalFormat); } return ret; }
QString CppClassType::toString() const { QualifiedIdentifier id = qualifiedIdentifier(); if (!id.isEmpty()) { if(declarationId().specialization().index()) return AbstractType::toString() + Cpp::IndexedInstantiationInformation(declarationId().specialization()).information().applyToIdentifier(id).toString(); else return AbstractType::toString() + id.toString(); } //This path usually is not taken QString type = "class"; return QString("<%1>%2").arg(type).arg(AbstractType::toString(true)); }
QString DeclarationNavigationContext::html(bool shorten) { clear(); m_shorten = shorten; modifyHtml() += "<html><body><p>" + fontSizePrefix(shorten); addExternalHtml(m_prefix); if(!m_declaration.data()) { modifyHtml() += i18n("<br /> lost declaration <br />"); return currentHtml(); } if( m_previousContext ) { QString link = createLink( m_previousContext->name(), m_previousContext->name(), NavigationAction(m_previousContext) ); modifyHtml() += navigationHighlight(i18n("Back to %1<br />", link)); } QExplicitlySharedDataPointer<IDocumentation> doc; if( !shorten ) { doc = ICore::self()->documentationController()->documentationForDeclaration(m_declaration.data()); const AbstractFunctionDeclaration* function = dynamic_cast<const AbstractFunctionDeclaration*>(m_declaration.data()); if( function ) { htmlFunction(); } else if( m_declaration->isTypeAlias() || m_declaration->kind() == Declaration::Instance ) { if( m_declaration->isTypeAlias() ) modifyHtml() += importantHighlight("type "); if(m_declaration->type<EnumeratorType>()) modifyHtml() += i18n("enumerator "); if( !m_declaration->isTypeAlias()) modifyHtml() += ' ' + identifierHighlight(declarationName(m_declaration).toHtmlEscaped(), m_declaration) + " "; AbstractType::Ptr useType = m_declaration->abstractType(); if(m_declaration->isTypeAlias()) { //Do not show the own name as type of typedefs if(useType.cast<TypeAliasType>()) useType = useType.cast<TypeAliasType>()->type(); } eventuallyMakeTypeLinks( useType ); modifyHtml() += "<br>"; }else{ if( m_declaration->kind() == Declaration::Type && m_declaration->abstractType().cast<StructureType>()) { htmlClass(); } if ( m_declaration->kind() == Declaration::Namespace ) { modifyHtml() += i18n("namespace %1 ", identifierHighlight(m_declaration->qualifiedIdentifier().toString().toHtmlEscaped(), m_declaration)); } if(m_declaration->type<EnumerationType>()) { EnumerationType::Ptr enumeration = m_declaration->type<EnumerationType>(); modifyHtml() += i18n("enumeration %1 ", identifierHighlight(m_declaration->identifier().toString().toHtmlEscaped(), m_declaration)); } if(m_declaration->isForwardDeclaration()) { ForwardDeclaration* forwardDec = static_cast<ForwardDeclaration*>(m_declaration.data()); Declaration* resolved = forwardDec->resolve(m_topContext.data()); if(resolved) { modifyHtml() += i18n("( resolved forward-declaration: "); makeLink(resolved->identifier().toString(), KDevelop::DeclarationPointer(resolved), NavigationAction::NavigateDeclaration ); modifyHtml() += i18n(") "); }else{ modifyHtml() += i18n("(unresolved forward-declaration) "); QualifiedIdentifier id = forwardDec->qualifiedIdentifier(); uint count; const IndexedDeclaration* decls; PersistentSymbolTable::self().declarations(id, count, decls); for(uint a = 0; a < count; ++a) { if(decls[a].isValid() && !decls[a].data()->isForwardDeclaration()) { modifyHtml() += "<br />"; makeLink(i18n("possible resolution from"), KDevelop::DeclarationPointer(decls[a].data()), NavigationAction::NavigateDeclaration); modifyHtml() += ' ' + decls[a].data()->url().str(); } } } } modifyHtml() += "<br />"; } }else{ AbstractType::Ptr showType = m_declaration->abstractType(); if(showType && showType.cast<FunctionType>()) { showType = showType.cast<FunctionType>()->returnType(); if(showType) modifyHtml() += labelHighlight(i18n("Returns: ")); }else if(showType) { modifyHtml() += labelHighlight(i18n("Type: ")); } if(showType) { eventuallyMakeTypeLinks(showType); modifyHtml() += " "; } } QualifiedIdentifier identifier = m_declaration->qualifiedIdentifier(); if( identifier.count() > 1 ) { if( m_declaration->context() && m_declaration->context()->owner() ) { Declaration* decl = m_declaration->context()->owner(); FunctionDefinition* definition = dynamic_cast<FunctionDefinition*>(decl); if(definition && definition->declaration()) decl = definition->declaration(); if(decl->abstractType().cast<EnumerationType>()) modifyHtml() += labelHighlight(i18n("Enum: ")); else modifyHtml() += labelHighlight(i18n("Container: ")); makeLink( declarationName(DeclarationPointer(decl)), DeclarationPointer(decl), NavigationAction::NavigateDeclaration ); modifyHtml() += " "; } else { QualifiedIdentifier parent = identifier; parent.pop(); modifyHtml() += labelHighlight(i18n("Scope: %1 ", typeHighlight(parent.toString().toHtmlEscaped()))); } } if( shorten && !m_declaration->comment().isEmpty() ) { QString comment = QString::fromUtf8(m_declaration->comment()); if( comment.length() > 60 ) { comment.truncate(60); comment += "..."; } comment.replace('\n', " "); comment.replace("<br />", " "); comment.replace("<br/>", " "); modifyHtml() += commentHighlight(comment.toHtmlEscaped()) + " "; } QString access = stringFromAccess(m_declaration); if( !access.isEmpty() ) modifyHtml() += labelHighlight(i18n("Access: %1 ", propertyHighlight(access.toHtmlEscaped()))); ///@todo Enumerations QString detailsHtml; QStringList details = declarationDetails(m_declaration); if( !details.isEmpty() ) { bool first = true; foreach( const QString &str, details ) { if( !first ) detailsHtml += ", "; first = false; detailsHtml += propertyHighlight(str); } }