Commit e36d609e authored by Milian Wolff's avatar Milian Wolff

Associate a declaration with ImplementsItem.

This allows us to use ALT to show the expanding widget for the
function we could implement, showing us the documentation and
other meta information.
parent 14727195
......@@ -24,6 +24,7 @@
#include "../duchain/cursorkindtraits.h"
#include "../duchain/parsesession.h"
#include "../duchain/documentfinderhelpers.h"
#include "../duchain/clanghelpers.h"
#include "../util/clangdebug.h"
#include "../util/clangtypes.h"
#include "../util/clangutils.h"
......@@ -292,9 +293,14 @@ CXChildVisitResult declVisitor(CXCursor cursor, CXCursor parent, CXClientData d)
//TODO Add support for pure virtual functions
data->prototypes->append(FuncImplementInfo{kind == CXCursor_Constructor,
kind == CXCursor_Destructor,
data->templatePrefix, returnType, rest});
ReferencedTopDUContext top;
{
DUChainReadLocker lock;
top = DUChain::self()->chainForDocument(ClangString(clang_getFileName(file)).toIndexed());
}
DeclarationPointer declaration = ClangHelpers::findDeclaration(clang_getCursorLocation(cursor), top);
data->prototypes->append(FuncImplementInfo{kind == CXCursor_Constructor, kind == CXCursor_Destructor,
data->templatePrefix, returnType, rest, declaration});
return CXChildVisit_Continue;
}
......
......@@ -45,6 +45,7 @@ struct FuncImplementInfo
QString templatePrefix;
QString returnType;
QString prototype;
KDevelop::DeclarationPointer declaration;
};
namespace KTextEditor {
......
......@@ -166,44 +166,6 @@ private:
QString m_returnType;
};
class ImplementsItem : public CompletionItem<CompletionTreeItem>
{
public:
ImplementsItem(const FuncImplementInfo& item)
: CompletionItem<KDevelop::CompletionTreeItem>(
item.prototype,
i18n("Implement %1", item.isConstructor ? QStringLiteral("<constructor>") :
item.isDestructor ? QStringLiteral("<destructor>") : item.returnType)
)
, m_item(item)
{
}
QVariant data(const QModelIndex& index, int role, const CodeCompletionModel* model) const override
{
if (role == Qt::DecorationRole) {
if (index.column() == KTextEditor::CodeCompletionModel::Icon) {
static const QIcon icon = QIcon::fromTheme(QStringLiteral("CTsuppliers"));
return icon;
}
}
return CompletionItem<CompletionTreeItem>::data(index, role, model);
}
void execute(KTextEditor::View* view, const KTextEditor::Range& word) override
{
QString replacement = m_item.templatePrefix;
if (!m_item.isDestructor && !m_item.isConstructor) {
replacement += m_item.returnType + QLatin1Char(' ');
}
replacement += m_item.prototype + QLatin1String("\n{\n}\n");
view->document()->replaceText(word, replacement);
}
private:
FuncImplementInfo m_item;
};
/**
* Specialized completion item class for items which are represented by a Declaration
*/
......@@ -290,12 +252,48 @@ public:
m_depth = depth;
}
private:
protected:
int m_matchQuality = 0;
int m_depth = 0;
QString m_replacement;
};
class ImplementsItem : public DeclarationItem
{
public:
static QString replacement(const FuncImplementInfo& info)
{
QString replacement = info.templatePrefix;
if (!info.isDestructor && !info.isConstructor) {
replacement += info.returnType + QLatin1Char(' ');
}
replacement += info.prototype + QLatin1String("\n{\n}\n");
return replacement;
}
ImplementsItem(const FuncImplementInfo& item)
: DeclarationItem(item.declaration.data(), item.prototype,
i18n("Implement %1", item.isConstructor ? QStringLiteral("<constructor>") :
item.isDestructor ? QStringLiteral("<destructor>") : item.returnType),
replacement(item)
)
{
}
QVariant data(const QModelIndex& index, int role, const CodeCompletionModel* model) const override
{
if (index.column() == CodeCompletionModel::Arguments) {
// our display string already contains the arguments
return {};
}
return DeclarationItem::data(index, role, model);
}
void execute(KTextEditor::View* view, const KTextEditor::Range& word) override
{
view->document()->replaceText(word, m_replacement);
}
};
class ArgumentHintItem : public DeclarationItem
{
......
......@@ -183,33 +183,37 @@ ReferencedTopDUContext ClangHelpers::buildDUChain(CXFile file, const Imports& im
return context;
}
DeclarationPointer ClangHelpers::findDeclaration(CXCursor cursor, const IncludeFileContexts& includes)
DeclarationPointer ClangHelpers::findDeclaration(CXSourceLocation location, const ReferencedTopDUContext& top)
{
auto refLoc = clang_getCursorLocation(cursor);
CXFile file = nullptr;
clang_getFileLocation(refLoc, &file, nullptr, nullptr, nullptr);
if (!file) {
return {};
}
auto refCursor = CursorInRevision(ClangLocation(refLoc));
const auto& top = includes.value(file);
if (!top) {
// may happen for cyclic includes
return {};
}
auto cursor = CursorInRevision(ClangLocation(location));
DUChainReadLocker lock;
Q_ASSERT(top);
if (DUContext *local = top->findContextAt(refCursor)) {
if (local->owner() && local->owner()->range().contains(refCursor)) {
if (DUContext *local = top->findContextAt(cursor)) {
if (local->owner() && local->owner()->range().contains(cursor)) {
return DeclarationPointer(local->owner());
}
return DeclarationPointer(local->findDeclarationAt(refCursor));
return DeclarationPointer(local->findDeclarationAt(cursor));
}
return {};
}
DeclarationPointer ClangHelpers::findDeclaration(CXCursor cursor, const IncludeFileContexts& includes)
{
auto location = clang_getCursorLocation(cursor);
CXFile file = nullptr;
clang_getFileLocation(location, &file, nullptr, nullptr, nullptr);
if (!file) {
return {};
}
return findDeclaration(location, includes.value(file));
}
DeclarationPointer ClangHelpers::findDeclaration(CXType type, const IncludeFileContexts& includes)
{
CXCursor cursor = clang_getTypeDeclaration(type);
......
......@@ -42,6 +42,7 @@ using IncludeFileContexts = QHash<CXFile, KDevelop::ReferencedTopDUContext>;
namespace ClangHelpers {
KDevelop::DeclarationPointer findDeclaration(CXSourceLocation cursor, const KDevelop::ReferencedTopDUContext& top);
KDevelop::DeclarationPointer findDeclaration(CXCursor cursor, const IncludeFileContexts& includes);
KDevelop::DeclarationPointer findDeclaration(CXType type, const IncludeFileContexts& includes);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment