forked from qt-creator/qt-creator
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>
This commit is contained in:
@@ -27,6 +27,8 @@
|
||||
|
||||
#include "optional.h"
|
||||
|
||||
#include <QMetaType>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class LineColumn
|
||||
@@ -57,3 +59,5 @@ public:
|
||||
using OptionalLineColumn = optional<LineColumn>;
|
||||
|
||||
} // namespace Utils
|
||||
|
||||
Q_DECLARE_METATYPE(Utils::LineColumn)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
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 extraInfo.typeSpelling.toString() + QLatin1String(" ") + name;
|
||||
}
|
||||
|
||||
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 &)
|
||||
QFutureInterface<Core::LocatorFilterEntry> &, const QString &entry)
|
||||
{
|
||||
return QList<Core::LocatorFilterEntry>();
|
||||
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));
|
||||
}
|
||||
|
||||
void ClangCurrentDocumentFilter::accept(Core::LocatorFilterEntry, QString *, int *, int *) const
|
||||
{
|
||||
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
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
|
||||
#include <coreplugin/locator/ilocatorfilter.h>
|
||||
|
||||
namespace Core { class IEditor; }
|
||||
|
||||
namespace ClangCodeModel {
|
||||
|
||||
class ClangCurrentDocumentFilter : public Core::ILocatorFilter
|
||||
@@ -41,6 +43,14 @@ public:
|
||||
void accept(Core::LocatorFilterEntry selection,
|
||||
QString *newText, int *selectionStart, int *selectionLength) const override;
|
||||
void refresh(QFutureInterface<void> &future) override;
|
||||
private:
|
||||
void onEditorAboutToClose(Core::IEditor *editors);
|
||||
void onCurrentEditorChanged(Core::IEditor *newCurrent);
|
||||
|
||||
void reset();
|
||||
|
||||
Core::IEditor *m_currentEditor = nullptr;
|
||||
QString m_currentPath;
|
||||
};
|
||||
|
||||
} // namespace ClangCodeModel
|
||||
|
||||
@@ -89,6 +89,9 @@ ModelManagerSupportClang::ModelManagerSupportClang()
|
||||
else
|
||||
m_followSymbol.reset(new CppTools::FollowSymbolUnderCursor);
|
||||
|
||||
CppTools::CppModelManager::instance()->setCurrentDocumentFilter(
|
||||
std::make_unique<ClangCurrentDocumentFilter>());
|
||||
|
||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||
connect(editorManager, &Core::EditorManager::editorOpened,
|
||||
this, &ModelManagerSupportClang::onEditorOpened);
|
||||
|
||||
Reference in New Issue
Block a user