Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Commit eb919e5c authored by Milian Wolff's avatar Milian Wolff

Initial proof-of-concept for code completion.

It is very shaky still, and requires a parsed DUChain with an
attached ParseSession to get the TU. Furthermore, the file must be
saved as otherwise the ranges won't match.
parent 3c3a13d1
......@@ -49,6 +49,7 @@ include_directories(
)
add_subdirectory(duchain)
add_subdirectory(codecompletion)
add_subdirectory(tests)
kde4_add_plugin(kdevclanglanguagesupport
......@@ -58,6 +59,7 @@ kde4_add_plugin(kdevclanglanguagesupport
)
target_link_libraries(kdevclanglanguagesupport
kdevclangduchain
kdevclangcodecompletion
${KDE4_THREADWEAVER_LIBS}
${KDEVPLATFORM_PROJECT_LIBRARIES}
......
......@@ -24,9 +24,12 @@
#include "clangparsejob.h"
#include "clanghighlighting.h"
#include "duchain/clangtypes.h"
#include "version.h"
#include "duchain/clangtypes.h"
#include "codecompletion/model.h"
#include <KPluginFactory>
#include <KAboutData>
......@@ -46,6 +49,8 @@ ClangLanguageSupport::ClangLanguageSupport(QObject* parent, const QVariantList&
, m_index(new ClangIndex)
{
KDEV_USE_EXTENSION_INTERFACE(ILanguageSupport)
new KDevelop::CodeCompletion( this, new ClangCodeCompletionModel(this), name() );
}
ClangLanguageSupport::~ClangLanguageSupport()
......
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
kde4_add_library(kdevclangcodecompletion SHARED
model.cpp
context.cpp
)
target_link_libraries(kdevclangcodecompletion LINK_PRIVATE
${QT_QTCORE_LIBRARY}
)
target_link_libraries(kdevclangcodecompletion LINK_PUBLIC
kdevclangduchain
)
install(TARGETS kdevclangcodecompletion ${INSTALL_TARGETS_DEFAULT_ARGS})
/*
This file is part of KDevelop
Copyright 2013 Olivier de Gaalon <olivier.jg@gmail.com>
Copyright 2013 Milian Wolff <mail@milianw.de>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef CODECOMPLETIONEXPORT_H
#define CODECOMPLETIONEXPORT_H
/* needed for KDE_EXPORT macros */
#include <kdemacros.h>
#ifndef KDEVCLANGCODECOMPLETION_EXPORT
# ifdef MAKE_KDEV4CLANGCODECOMPLETION_LIB
# define KDEVCLANGCODECOMPLETION_EXPORT KDE_EXPORT
# else
# define KDEVCLANGCODECOMPLETION_EXPORT KDE_IMPORT
# endif
#endif
#endif
/*
* This file is part of KDevelop
* Copyright 2014 Milian Wolff <mail@milianw.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "context.h"
#include <language/duchain/duchainlock.h>
#include <language/duchain/ducontext.h>
#include <language/duchain/topducontext.h>
#include <language/interfaces/iastcontainer.h>
#include <language/codecompletion/codecompletionitem.h>
#include <language/codecompletion/codecompletionmodel.h>
#include "../duchain/parsesession.h"
#include "../duchain/clangtypes.h"
#include <memory>
#include <KTextEditor/Document>
using namespace KDevelop;
namespace {
class Item : public CompletionTreeItem
{
public:
Item(const CXCompletionResult& result);
virtual ~Item() = default;
virtual QVariant data(const QModelIndex& index, int role, const CodeCompletionModel* model) const;
virtual void execute(KTextEditor::Document* document, const KTextEditor::Range& word);
private:
QString m_typed;
QString m_text;
QString m_result;
QString m_currParam;
};
Item::Item(const CXCompletionResult& result)
{
const uint chunks = clang_getNumCompletionChunks(result.CompletionString);
for (uint i = 0; i < chunks; ++i) {
const auto kind = clang_getCompletionChunkKind(result.CompletionString, i);
const QString string = ClangString(clang_getCompletionChunkText(result.CompletionString, i)).toString();
switch (kind) {
case CXCompletionChunk_TypedText:
m_typed = string;
break;
case CXCompletionChunk_CurrentParameter:
m_currParam = string;
continue;
case CXCompletionChunk_ResultType:
m_result = string;
continue;
case CXCompletionChunk_Informative:
case CXCompletionChunk_Optional:
continue;
case CXCompletionChunk_Placeholder:
m_text += "/*" + string + "*/";
continue;
}
m_text += string;
}
}
QVariant Item::data(const QModelIndex& index, int role, const CodeCompletionModel* /*model*/) const
{
if (role != Qt::DisplayRole) {
return {};
}
switch (index.column()) {
case CodeCompletionModel::Name:
return m_typed;
case CodeCompletionModel::Prefix:
return m_result;
}
return {};
}
void Item::execute(KTextEditor::Document* document, const KTextEditor::Range& word)
{
document->replaceText(word, m_text);
}
}
ClangCodeCompletionContext::ClangCodeCompletionContext(const DUContextPointer& context, const QString& text,
const CursorInRevision& position, int depth)
: CodeCompletionContext(context, text, position, depth)
{
}
ClangCodeCompletionContext::~ClangCodeCompletionContext()
{
}
QList<CompletionTreeItemPointer> ClangCodeCompletionContext::completionItems(bool& abort, bool /*fullCompletion*/)
{
// FIXME: ensure we don't access the TU from this thread and the parse thread simultaneously!
DUChainReadLocker lock;
if (abort) {
return {};
}
const auto session = KSharedPtr<ParseSession>::dynamicCast(m_duContext->topContext()->ast());
if (!session) {
qDebug() << "no session found for file" << m_duContext->url();
return {};
}
ClangString file(clang_getFileName(session->file()));
/* FIXME: m_text only contains the part of the current context which is not enough for the clang use-case
CXUnsavedFile unsaved;
const auto contents = m_text.toUtf8();
unsaved.Contents = contents.constData();
unsaved.Length = contents.size();
unsaved.Filename = file;
*/
const auto results = std::unique_ptr<CXCodeCompleteResults, void(*)(CXCodeCompleteResults*)>(
clang_codeCompleteAt(session->unit(), file, m_position.line + 1, m_position.column + 1, nullptr, 0,
clang_defaultCodeCompleteOptions()),
clang_disposeCodeCompleteResults);
QList<CompletionTreeItemPointer> ret;
ret.reserve(results->NumResults);
for (uint i = 0; i < results->NumResults; ++i) {
ret.append(CompletionTreeItemPointer(new Item(results->Results[i])));
}
return ret;
}
/*
* This file is part of KDevelop
* Copyright 2014 Milian Wolff <mail@milianw.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLANGCODECOMPLETIONCONTEXT_H
#define CLANGCODECOMPLETIONCONTEXT_H
#include <language/codecompletion/codecompletioncontext.h>
class ClangCodeCompletionContext : public KDevelop::CodeCompletionContext
{
public:
ClangCodeCompletionContext(const KDevelop::DUContextPointer& context, const QString& text,
const KDevelop::CursorInRevision& position, int depth = 0);
~ClangCodeCompletionContext();
QList< KDevelop::CompletionTreeItemPointer > completionItems(bool& abort, bool fullCompletion) override;
};
#endif // CLANGCODECOMPLETIONCONTEXT_H
/*
* This file is part of KDevelop
* Copyright 2014 Milian Wolff <mail@milianw.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "model.h"
#include "context.h"
#include <language/codecompletion/codecompletionworker.h>
using namespace KDevelop;
namespace {
class ClangCodeCompletionWorker : public CodeCompletionWorker
{
Q_OBJECT
public:
ClangCodeCompletionWorker(CodeCompletionModel* model)
: CodeCompletionWorker(model)
{}
virtual ~ClangCodeCompletionWorker()
{}
CodeCompletionContext* createCompletionContext(DUContextPointer context, const QString& contextText,
const QString& /*followingText*/, const CursorInRevision& position) const override
{
return new ClangCodeCompletionContext(context, contextText, position);
}
};
}
ClangCodeCompletionModel::ClangCodeCompletionModel(QObject* parent)
: CodeCompletionModel(parent)
{
}
ClangCodeCompletionModel::~ClangCodeCompletionModel()
{
}
CodeCompletionWorker* ClangCodeCompletionModel::createCompletionWorker()
{
return new ClangCodeCompletionWorker(this);
}
#include "model.moc"
#include "moc_model.cpp"
/*
* This file is part of KDevelop
* Copyright 2014 Milian Wolff <mail@milianw.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef CLANGCODECOMPLETIONMODEL_H
#define CLANGCODECOMPLETIONMODEL_H
#include <language/codecompletion/codecompletionmodel.h>
#include "codecompletionexport.h"
class KDEVCLANGCODECOMPLETION_EXPORT ClangCodeCompletionModel : public KDevelop::CodeCompletionModel
{
Q_OBJECT
public:
explicit ClangCodeCompletionModel(QObject* parent);
virtual ~ClangCodeCompletionModel();
protected:
virtual KDevelop::CodeCompletionWorker* createCompletionWorker();
};
#endif // CLANGCODECOMPLETIONMODEL_H
......@@ -57,6 +57,11 @@ ClangString::operator const char*() const
return data ? data : "";
}
QString ClangString::toString() const
{
return QString::fromUtf8(clang_getCString(string));
}
ClangLocation::ClangLocation(CXSourceLocation location)
: location(location)
{
......
......@@ -60,6 +60,8 @@ public:
operator const char*() const;
QString toString() const;
private:
CXString string;
};
......
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