diff options
author | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2017-11-27 15:51:18 +0100 |
---|---|---|
committer | Ivan Donchevskii <ivan.donchevskii@qt.io> | 2018-02-20 14:03:53 +0000 |
commit | 432ae65944701980a8fc792d25d792e40968db08 (patch) | |
tree | 936920f9f87994023eb521b7f06731bddcb05d24 /src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp | |
parent | c39f28d5e03bc336952fa5a7b21b4c892bc7e699 (diff) |
Clang: implement current document filter
Filter is based on full token infos which come
from clang code model after token infos with pure
highlighting information.
Inprovements:
- functions also provide the return type after the signature
- now supports Q_PROPERTY
- all c++ features that clang 5.0 supports
Change-Id: If3e30d238984f39df8d2c3b9ba3ee085c4117f3d
Reviewed-by: Marco Bubke <marco.bubke@qt.io>
Diffstat (limited to 'src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp')
-rw-r--r-- | src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp | 137 |
1 files changed, 133 insertions, 4 deletions
diff --git a/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp b/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp index b28ac972918..d5a84b611d4 100644 --- a/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp +++ b/src/plugins/clangcodemodel/clangcurrentdocumentfilter.cpp @@ -25,8 +25,28 @@ #include "clangcurrentdocumentfilter.h" +#include "clangeditordocumentprocessor.h" +#include "clangutils.h" + +#include <clangsupport/tokeninfocontainer.h> + +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/editormanager/ieditor.h> + +#include <cplusplus/Icons.h> + #include <cpptools/cpptoolsconstants.h> +#include <texteditor/textdocument.h> + +#include <utils/algorithm.h> +#include <utils/fuzzymatcher.h> +#include <utils/linecolumn.h> +#include <utils/textutils.h> +#include <utils/qtcassert.h> + +#include <QRegularExpression> + namespace ClangCodeModel { ClangCurrentDocumentFilter::ClangCurrentDocumentFilter() @@ -36,22 +56,131 @@ ClangCurrentDocumentFilter::ClangCurrentDocumentFilter() setShortcutString(QString(QLatin1Char('.'))); setPriority(High); setIncludedByDefault(false); + + Core::EditorManager *editorManager = Core::EditorManager::instance(); + connect(editorManager, &Core::EditorManager::currentEditorChanged, + this, &ClangCurrentDocumentFilter::onCurrentEditorChanged, + Qt::QueuedConnection); + connect(editorManager, &Core::EditorManager::editorAboutToClose, + this, &ClangCurrentDocumentFilter::onEditorAboutToClose, + Qt::QueuedConnection); } -QList<Core::LocatorFilterEntry> ClangCurrentDocumentFilter::matchesFor( - QFutureInterface<Core::LocatorFilterEntry> &, const QString &) +static QString addResultTypeToFunctionSignature(const QString &signature, + const ClangBackEnd::ExtraInfo &extraInfo) +{ + return signature + extraInfo.typeSpelling.toString() + QLatin1String(" -> ", 4) + + extraInfo.resultTypeSpelling.toString(); +} + +static QString addTypeToVariableName(const QString &name, const ClangBackEnd::ExtraInfo &extraInfo) { - return QList<Core::LocatorFilterEntry>(); + return extraInfo.typeSpelling.toString() + QLatin1String(" ") + name; } -void ClangCurrentDocumentFilter::accept(Core::LocatorFilterEntry, QString *, int *, int *) const +static Core::LocatorFilterEntry makeEntry(Core::ILocatorFilter *filter, + const ClangBackEnd::TokenInfoContainer &info) +{ + const ClangBackEnd::ExtraInfo &extraInfo = info.extraInfo(); + QString displayName = extraInfo.token; + ::Utils::LineColumn lineColumn(static_cast<int>(info.line()), + static_cast<int>(info.column())); + Core::LocatorFilterEntry entry(filter, displayName, qVariantFromValue(lineColumn)); + QString extra; + ClangBackEnd::HighlightingType mainType = info.types().mainHighlightingType; + if (mainType == ClangBackEnd::HighlightingType::VirtualFunction + || mainType == ClangBackEnd::HighlightingType::Function) { + displayName = addResultTypeToFunctionSignature(displayName, extraInfo); + extra = extraInfo.semanticParentTypeSpelling.toString(); + } else if (mainType == ClangBackEnd::HighlightingType::GlobalVariable + || mainType == ClangBackEnd::HighlightingType::Field + || mainType == ClangBackEnd::HighlightingType::QtProperty) { + displayName = addTypeToVariableName(displayName, extraInfo); + extra = extraInfo.semanticParentTypeSpelling.toString(); + } else { + extra = extraInfo.typeSpelling.toString(); + } + entry.displayName = displayName; + entry.extraInfo = extra; + entry.displayIcon = CPlusPlus::Icons::iconForType(Utils::iconTypeForToken(info)); + return entry; +} + +QList<Core::LocatorFilterEntry> ClangCurrentDocumentFilter::matchesFor( + QFutureInterface<Core::LocatorFilterEntry> &, const QString &entry) { + QList<Core::LocatorFilterEntry> goodEntries; + if (!m_currentEditor) + return goodEntries; + FuzzyMatcher::CaseSensitivity caseSesitivity = caseSensitivity(entry) == Qt::CaseSensitive + ? FuzzyMatcher::CaseSensitivity::CaseSensitive + : FuzzyMatcher::CaseSensitivity::CaseInsensitive; + const QRegularExpression regexp = FuzzyMatcher::createRegExp(entry, caseSesitivity); + if (!regexp.isValid()) + return goodEntries; + + using Internal::ClangEditorDocumentProcessor; + ClangEditorDocumentProcessor *processor = ClangEditorDocumentProcessor::get(m_currentPath); + if (!processor) + return goodEntries; + + using TokInfoContainer = ClangBackEnd::TokenInfoContainer; + const QVector<TokInfoContainer> &infos = processor->tokenInfos(); + + for (const TokInfoContainer &info : infos) { + if (!info.extraInfo().declaration) + continue; + if (info.types().mainHighlightingType == ClangBackEnd::HighlightingType::LocalVariable) + continue; + QRegularExpressionMatch match = regexp.match(info.extraInfo().token); + if (match.hasMatch()) + goodEntries.push_back(makeEntry(this, info)); + } + + return goodEntries; +} + +void ClangCurrentDocumentFilter::accept(Core::LocatorFilterEntry selection, + QString *, int *, int *) const +{ + if (!m_currentEditor) + return; + auto lineColumn = qvariant_cast<::Utils::LineColumn>(selection.internalData); + Core::EditorManager::openEditorAt(m_currentPath, lineColumn.line, + lineColumn.column - 1); } void ClangCurrentDocumentFilter::refresh(QFutureInterface<void> &) { +} + +void ClangCurrentDocumentFilter::reset() +{ + m_currentEditor = nullptr; + m_currentPath.clear(); +} + +void ClangCurrentDocumentFilter::onEditorAboutToClose(Core::IEditor *editorAboutToClose) +{ + if (!editorAboutToClose) + return; + + if (m_currentEditor == editorAboutToClose) + reset(); +} +void ClangCurrentDocumentFilter::onCurrentEditorChanged(Core::IEditor *newCurrent) +{ + if (newCurrent) { + m_currentEditor = newCurrent; + Core::IDocument *document = m_currentEditor->document(); + QTC_ASSERT(document, return;); + auto *textDocument = qobject_cast<TextEditor::TextDocument *>(document); + m_currentPath = textDocument->filePath().toString(); + } else { + reset(); + } } } // namespace ClangCodeModel |