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 "optional.h"
|
||||||
|
|
||||||
|
#include <QMetaType>
|
||||||
|
|
||||||
namespace Utils {
|
namespace Utils {
|
||||||
|
|
||||||
class LineColumn
|
class LineColumn
|
||||||
@@ -57,3 +59,5 @@ public:
|
|||||||
using OptionalLineColumn = optional<LineColumn>;
|
using OptionalLineColumn = optional<LineColumn>;
|
||||||
|
|
||||||
} // namespace Utils
|
} // namespace Utils
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(Utils::LineColumn)
|
||||||
|
|||||||
@@ -25,8 +25,28 @@
|
|||||||
|
|
||||||
#include "clangcurrentdocumentfilter.h"
|
#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 <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 {
|
namespace ClangCodeModel {
|
||||||
|
|
||||||
ClangCurrentDocumentFilter::ClangCurrentDocumentFilter()
|
ClangCurrentDocumentFilter::ClangCurrentDocumentFilter()
|
||||||
@@ -36,22 +56,131 @@ ClangCurrentDocumentFilter::ClangCurrentDocumentFilter()
|
|||||||
setShortcutString(QString(QLatin1Char('.')));
|
setShortcutString(QString(QLatin1Char('.')));
|
||||||
setPriority(High);
|
setPriority(High);
|
||||||
setIncludedByDefault(false);
|
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(
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
return goodEntries;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClangCurrentDocumentFilter::accept(Core::LocatorFilterEntry, QString *, int *, int *) const
|
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::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
|
} // namespace ClangCodeModel
|
||||||
|
|||||||
@@ -27,6 +27,8 @@
|
|||||||
|
|
||||||
#include <coreplugin/locator/ilocatorfilter.h>
|
#include <coreplugin/locator/ilocatorfilter.h>
|
||||||
|
|
||||||
|
namespace Core { class IEditor; }
|
||||||
|
|
||||||
namespace ClangCodeModel {
|
namespace ClangCodeModel {
|
||||||
|
|
||||||
class ClangCurrentDocumentFilter : public Core::ILocatorFilter
|
class ClangCurrentDocumentFilter : public Core::ILocatorFilter
|
||||||
@@ -41,6 +43,14 @@ public:
|
|||||||
void accept(Core::LocatorFilterEntry selection,
|
void accept(Core::LocatorFilterEntry selection,
|
||||||
QString *newText, int *selectionStart, int *selectionLength) const override;
|
QString *newText, int *selectionStart, int *selectionLength) const override;
|
||||||
void refresh(QFutureInterface<void> &future) 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
|
} // namespace ClangCodeModel
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ ModelManagerSupportClang::ModelManagerSupportClang()
|
|||||||
else
|
else
|
||||||
m_followSymbol.reset(new CppTools::FollowSymbolUnderCursor);
|
m_followSymbol.reset(new CppTools::FollowSymbolUnderCursor);
|
||||||
|
|
||||||
|
CppTools::CppModelManager::instance()->setCurrentDocumentFilter(
|
||||||
|
std::make_unique<ClangCurrentDocumentFilter>());
|
||||||
|
|
||||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
connect(editorManager, &Core::EditorManager::editorOpened,
|
connect(editorManager, &Core::EditorManager::editorOpened,
|
||||||
this, &ModelManagerSupportClang::onEditorOpened);
|
this, &ModelManagerSupportClang::onEditorOpened);
|
||||||
|
|||||||
Reference in New Issue
Block a user