File indexing completed on 2024-04-21 15:24:07

0001 /*
0002     SPDX-FileCopyrightText: 2012 Milian Wolff <mail@milianw.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "phpdocsmodel.h"
0008 
0009 #include "phpdocsdebug.h"
0010 
0011 #include <language/duchain/duchain.h>
0012 #include <language/duchain/declaration.h>
0013 #include <language/duchain/duchainlock.h>
0014 
0015 #include <language/duchain/types/structuretype.h>
0016 
0017 #include <interfaces/icore.h>
0018 #include <interfaces/ilanguagecontroller.h>
0019 #include <language/backgroundparser/backgroundparser.h>
0020 #include <language/backgroundparser/parsejob.h>
0021 
0022 #include <KLocalizedString>
0023 
0024 #include <QStandardPaths>
0025 
0026 using namespace KDevelop;
0027 
0028 PhpDocsModel::PhpDocsModel(QObject* parent)
0029     : QAbstractListModel(parent), m_internalFunctionsFile(QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("kdevphpsupport/phpfunctions.php")))
0030 {
0031     // make sure the php plugin is loaded
0032     auto phpLangPlugin = ICore::self()->languageController()->language(QStringLiteral("Php"));
0033     if ( !phpLangPlugin ) {
0034         qCWarning(DOCS) << "could not load PHP language support plugin";
0035         return;
0036     }
0037 
0038     DUChain::self()->updateContextForUrl(internalFunctionFile(), TopDUContext::AllDeclarationsAndContexts, this, -10);
0039 }
0040 
0041 PhpDocsModel::~PhpDocsModel()
0042 {
0043 }
0044 
0045 IndexedString PhpDocsModel::internalFunctionFile() const
0046 {
0047     return m_internalFunctionsFile;
0048 }
0049 
0050 void PhpDocsModel::updateReady(const IndexedString& file, const ReferencedTopDUContext& top)
0051 {
0052     if ( file == m_internalFunctionsFile && top ) {
0053         fillModel(top);
0054     }
0055 }
0056 
0057 void PhpDocsModel::fillModel(const ReferencedTopDUContext& top)
0058 {
0059     DUChainReadLocker lock;
0060     if (!top) {
0061         return;
0062     }
0063 
0064     qCDebug(DOCS) << "filling model";
0065     typedef QPair<Declaration*, int> DeclDepthPair;
0066     foreach ( DeclDepthPair declpair, top->allDeclarations(top->range().end, top) ) {
0067         if ( declpair.first->abstractType() && declpair.first->abstractType()->modifiers() & AbstractType::ConstModifier ) {
0068             // filter global constants, since they are hard to find in the documentation
0069             continue;
0070         }
0071         m_declarations << DeclarationPointer(declpair.first);
0072 
0073         if ( StructureType::Ptr type = declpair.first->type<StructureType>() ) {
0074             foreach ( Declaration* dec, type->internalContext(top)->localDeclarations() ) {
0075                 m_declarations << DeclarationPointer(dec);
0076             }
0077         }
0078     }
0079 }
0080 
0081 bool PhpDocsModel::hasChildren(const QModelIndex& parent) const
0082 {
0083     // only the top-level has children
0084     return parent == QModelIndex();
0085 }
0086 
0087 QVariant PhpDocsModel::data(const QModelIndex& index, int role) const
0088 {
0089     switch ( role ) {
0090         case Qt::DisplayRole:
0091         case Qt::EditRole: {
0092             DUChainReadLocker lock;
0093             DeclarationPointer dec = declarationForIndex(index);
0094             if (!dec.data()) {
0095                 return i18n("<lost declaration>");
0096             }
0097             QString ret = dec->toString();
0098             if ( dec->isFunctionDeclaration() ) {
0099                 // remove function arguments
0100                 ret = ret.replace(QRegExp("\\(.+\\)"), QStringLiteral("()"));
0101                 // remove return type
0102                 ret = ret.remove(QRegExp("^[^ ]+ "));
0103             }
0104             return ret;
0105         }
0106         case DeclarationRole: {
0107             DeclarationPointer dec = declarationForIndex(index);
0108             return QVariant::fromValue<DeclarationPointer>(dec);
0109         }
0110         /*
0111         case Qt::ToolTipRole:
0112         case Qt::AccessibleTextRole:
0113         case Qt::AccessibleDescriptionRole:
0114         */
0115         default:
0116             return QVariant();
0117     }
0118 }
0119 
0120 int PhpDocsModel::rowCount(const QModelIndex& parent) const
0121 {
0122     if (parent.isValid())
0123         return 0;
0124 
0125     return m_declarations.count();
0126 }
0127 
0128 DeclarationPointer PhpDocsModel::declarationForIndex(const QModelIndex& index) const
0129 {
0130     Q_ASSERT(m_declarations.size() > index.row());
0131 
0132     return m_declarations[index.row()];
0133 }
0134 
0135 #include "moc_phpdocsmodel.cpp"