forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/7.0'
Conflicts: src/plugins/qmldesigner/components/itemlibrary/itemlibraryview.cpp Change-Id: Icda34067bb89d066a3e7eb47f8cca1d62dc3ae0d
This commit is contained in:
@@ -135,7 +135,7 @@ QList<Core::LocatorFilterEntry> ClangCurrentDocumentFilter::matchesFor(
|
||||
return goodEntries;
|
||||
}
|
||||
|
||||
void ClangCurrentDocumentFilter::accept(Core::LocatorFilterEntry selection,
|
||||
void ClangCurrentDocumentFilter::accept(const Core::LocatorFilterEntry &selection,
|
||||
QString *, int *, int *) const
|
||||
{
|
||||
if (!m_currentEditor)
|
||||
|
||||
@@ -42,7 +42,7 @@ public:
|
||||
void prepareSearch(const QString &entry) override;
|
||||
QList<Core::LocatorFilterEntry> matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||
const QString &entry) override;
|
||||
void accept(Core::LocatorFilterEntry selection,
|
||||
void accept(const Core::LocatorFilterEntry &selection,
|
||||
QString *newText, int *selectionStart, int *selectionLength) const override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -1095,6 +1095,7 @@ class MemoryUsageWidget : public QWidget
|
||||
Q_DECLARE_TR_FUNCTIONS(MemoryUsageWidget)
|
||||
public:
|
||||
MemoryUsageWidget(ClangdClient *client);
|
||||
~MemoryUsageWidget();
|
||||
|
||||
private:
|
||||
void setupUi();
|
||||
@@ -1103,6 +1104,7 @@ private:
|
||||
ClangdClient * const m_client;
|
||||
MemoryTreeModel * const m_model;
|
||||
Utils::TreeView m_view;
|
||||
Utils::optional<MessageId> m_currentRequest;
|
||||
};
|
||||
|
||||
class ClangdClient::Private
|
||||
@@ -1161,6 +1163,7 @@ public:
|
||||
std::unordered_map<TextDocument *, CppEditor::SemanticHighlighter *> highlighters;
|
||||
|
||||
QHash<TextDocument *, QPair<QList<ExpandedSemanticToken>, int>> previousTokens;
|
||||
QHash<Utils::FilePath, CppEditor::BaseEditorDocumentParser::Configuration> parserConfigs;
|
||||
|
||||
// The ranges of symbols referring to virtual functions, with document version,
|
||||
// as extracted by the highlighting procedure.
|
||||
@@ -1534,6 +1537,7 @@ void ClangdClient::handleDocumentClosed(TextDocument *doc)
|
||||
d->astCache.remove(doc);
|
||||
d->previousTokens.remove(doc);
|
||||
d->virtualRanges.remove(doc);
|
||||
d->parserConfigs.remove(doc->filePath());
|
||||
}
|
||||
|
||||
QTextCursor ClangdClient::adjustedCursorForHighlighting(const QTextCursor &cursor,
|
||||
@@ -1697,6 +1701,39 @@ void ClangdClient::handleUiHeaderChange(const QString &fileName)
|
||||
}
|
||||
}
|
||||
|
||||
void ClangdClient::updateParserConfig(const Utils::FilePath &filePath,
|
||||
const CppEditor::BaseEditorDocumentParser::Configuration &config)
|
||||
{
|
||||
if (config.preferredProjectPartId.isEmpty())
|
||||
return;
|
||||
|
||||
CppEditor::BaseEditorDocumentParser::Configuration &cachedConfig = d->parserConfigs[filePath];
|
||||
if (cachedConfig == config)
|
||||
return;
|
||||
cachedConfig = config;
|
||||
|
||||
// TODO: Also handle editorDefines (and usePrecompiledHeaders?)
|
||||
const auto projectPart = CppEditor::CppModelManager::instance()
|
||||
->projectPartForId(config.preferredProjectPartId);
|
||||
if (!projectPart)
|
||||
return;
|
||||
const CppEditor::ClangDiagnosticConfig projectWarnings = warningsConfigForProject(project());
|
||||
const QStringList projectOptions = optionsForProject(project());
|
||||
QJsonObject cdbChanges;
|
||||
QStringList args = createClangOptions(*projectPart, filePath.toString(), projectWarnings,
|
||||
projectOptions);
|
||||
args.prepend("clang");
|
||||
args.append(filePath.toString());
|
||||
QJsonObject value;
|
||||
value.insert("workingDirectory", filePath.parentDir().toString());
|
||||
value.insert("compilationCommand", QJsonArray::fromStringList(args));
|
||||
cdbChanges.insert(filePath.toUserOutput(), value);
|
||||
const QJsonObject settings({qMakePair(QString("compilationDatabaseChanges"), cdbChanges)});
|
||||
DidChangeConfigurationParams configChangeParams;
|
||||
configChangeParams.setSettings(settings);
|
||||
sendContent(DidChangeConfigurationNotification(configChangeParams));
|
||||
}
|
||||
|
||||
void ClangdClient::Private::handleFindUsagesResult(quint64 key, const QList<Location> &locations)
|
||||
{
|
||||
const auto refData = runningFindUsages.find(key);
|
||||
@@ -2604,7 +2641,7 @@ private:
|
||||
// clangd reports also the #ifs, #elses and #endifs around the disabled code as disabled,
|
||||
// and not even in a consistent manner. We don't want this, so we have to clean up here.
|
||||
// But note that we require this behavior, as otherwise we would not be able to grey out
|
||||
// e.g. empty lines after an #fdef, due to the lack of symbols.
|
||||
// e.g. empty lines after an #ifdef, due to the lack of symbols.
|
||||
static QList<BlockRange> cleanupDisabledCode(HighlightingResults &results, const QTextDocument *doc,
|
||||
const QString &docContent)
|
||||
{
|
||||
@@ -2630,8 +2667,13 @@ static QList<BlockRange> cleanupDisabledCode(HighlightingResults &results, const
|
||||
&& !content.startsWith(QLatin1String("#elif"))
|
||||
&& !content.startsWith(QLatin1String("#else"))
|
||||
&& !content.startsWith(QLatin1String("#endif"))) {
|
||||
++it;
|
||||
continue;
|
||||
static const QStringList ppSuffixes{"if", "ifdef", "elif", "else", "endif"};
|
||||
const QList<QStringView> contentList = content.split(' ', Qt::SkipEmptyParts);
|
||||
if (contentList.size() < 2 || contentList.first() != QLatin1String("#")
|
||||
|| !ppSuffixes.contains(contentList.at(1))) {
|
||||
++it;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasIfdefedOut) {
|
||||
@@ -2643,7 +2685,8 @@ static QList<BlockRange> cleanupDisabledCode(HighlightingResults &results, const
|
||||
}
|
||||
|
||||
if (wasIfdefedOut && (it + 1 == results.end()
|
||||
|| (it + 1)->textStyles.mainStyle != C_DISABLED_CODE)) {
|
||||
|| (it + 1)->textStyles.mainStyle != C_DISABLED_CODE
|
||||
|| (it + 1)->line != it->line + 1)) {
|
||||
// The #else or #endif that ends disabled code should not be disabled.
|
||||
const QTextBlock block = doc->findBlockByNumber(it->line - 1);
|
||||
ifdefedOutRanges << BlockRange(rangeStartPos, block.position());
|
||||
@@ -3261,7 +3304,8 @@ void ClangdCompletionItem::apply(TextDocumentManipulatorInterface &manipulator,
|
||||
QTextCursor cursor = manipulator.textCursorAt(rangeStart);
|
||||
cursor.movePosition(QTextCursor::EndOfWord);
|
||||
const QString textAfterCursor = manipulator.textAt(currentPos, cursor.position() - currentPos);
|
||||
if (textToBeInserted != textAfterCursor
|
||||
if (currentPos < cursor.position()
|
||||
&& textToBeInserted != textAfterCursor
|
||||
&& textToBeInserted.indexOf(textAfterCursor, currentPos - rangeStart) >= 0) {
|
||||
currentPos = cursor.position();
|
||||
}
|
||||
@@ -4033,6 +4077,12 @@ MemoryUsageWidget::MemoryUsageWidget(ClangdClient *client)
|
||||
getMemoryTree();
|
||||
}
|
||||
|
||||
MemoryUsageWidget::~MemoryUsageWidget()
|
||||
{
|
||||
if (m_currentRequest.has_value())
|
||||
m_client->cancelRequest(m_currentRequest.value());
|
||||
}
|
||||
|
||||
void MemoryUsageWidget::setupUi()
|
||||
{
|
||||
const auto layout = new QVBoxLayout(this);
|
||||
@@ -4052,11 +4102,13 @@ void MemoryUsageWidget::getMemoryTree()
|
||||
{
|
||||
Request<MemoryTree, std::nullptr_t, JsonObject> request("$/memoryUsage", {});
|
||||
request.setResponseCallback([this](decltype(request)::Response response) {
|
||||
m_currentRequest.reset();
|
||||
qCDebug(clangdLog) << "received memory usage response";
|
||||
if (const auto result = response.result())
|
||||
m_model->update(*result);
|
||||
});
|
||||
qCDebug(clangdLog) << "sending memory usage request";
|
||||
m_currentRequest = request.id();
|
||||
m_client->sendContent(request, ClangdClient::SendDocUpdates::Ignore);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cppeditor/baseeditordocumentparser.h>
|
||||
#include <cppeditor/cppcodemodelsettings.h>
|
||||
#include <cppeditor/refactoringengineinterface.h>
|
||||
#include <languageclient/client.h>
|
||||
@@ -90,6 +91,9 @@ public:
|
||||
|
||||
static void handleUiHeaderChange(const QString &fileName);
|
||||
|
||||
void updateParserConfig(const Utils::FilePath &filePath,
|
||||
const CppEditor::BaseEditorDocumentParser::Configuration &config);
|
||||
|
||||
signals:
|
||||
void indexingFinished();
|
||||
void foundReferences(const QList<Core::SearchResultItem> &items);
|
||||
|
||||
@@ -198,7 +198,7 @@ QList<Core::LocatorFilterEntry> ClangGlobalSymbolFilter::matchesFor(
|
||||
return matches;
|
||||
}
|
||||
|
||||
void ClangGlobalSymbolFilter::accept(Core::LocatorFilterEntry selection, QString *newText,
|
||||
void ClangGlobalSymbolFilter::accept(const Core::LocatorFilterEntry &selection, QString *newText,
|
||||
int *selectionStart, int *selectionLength) const
|
||||
{
|
||||
if (qvariant_cast<CppEditor::IndexItem::Ptr>(selection.internalData))
|
||||
@@ -318,7 +318,7 @@ QList<Core::LocatorFilterEntry> ClangdCurrentDocumentFilter::matchesFor(
|
||||
return d->activeFilter->matchesFor(future, entry);
|
||||
}
|
||||
|
||||
void ClangdCurrentDocumentFilter::accept(Core::LocatorFilterEntry selection, QString *newText,
|
||||
void ClangdCurrentDocumentFilter::accept(const Core::LocatorFilterEntry &selection, QString *newText,
|
||||
int *selectionStart, int *selectionLength) const
|
||||
{
|
||||
QTC_ASSERT(d->activeFilter, return);
|
||||
|
||||
@@ -41,7 +41,7 @@ private:
|
||||
void prepareSearch(const QString &entry) override;
|
||||
QList<Core::LocatorFilterEntry> matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||
const QString &entry) override;
|
||||
void accept(Core::LocatorFilterEntry selection, QString *newText,
|
||||
void accept(const Core::LocatorFilterEntry &selection, QString *newText,
|
||||
int *selectionStart, int *selectionLength) const override;
|
||||
|
||||
Core::ILocatorFilter * const m_cppFilter;
|
||||
@@ -70,7 +70,7 @@ private:
|
||||
void prepareSearch(const QString &entry) override;
|
||||
QList<Core::LocatorFilterEntry> matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future,
|
||||
const QString &entry) override;
|
||||
void accept(Core::LocatorFilterEntry selection, QString *newText,
|
||||
void accept(const Core::LocatorFilterEntry &selection, QString *newText,
|
||||
int *selectionStart, int *selectionLength) const override;
|
||||
|
||||
class Private;
|
||||
|
||||
@@ -328,6 +328,12 @@ void ClangEditorDocumentProcessor::setParserConfig(
|
||||
{
|
||||
m_parser->setConfiguration(config);
|
||||
m_builtinProcessor.parser()->setConfiguration(config);
|
||||
emit parserConfigChanged(Utils::FilePath::fromString(filePath()), config);
|
||||
}
|
||||
|
||||
CppEditor::BaseEditorDocumentParser::Configuration ClangEditorDocumentProcessor::parserConfig() const
|
||||
{
|
||||
return m_parser->configuration();
|
||||
}
|
||||
|
||||
static bool isCursorOnIdentifier(const QTextCursor &textCursor)
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
void editorDocumentTimerRestarted() override;
|
||||
|
||||
void setParserConfig(const CppEditor::BaseEditorDocumentParser::Configuration &config) override;
|
||||
CppEditor::BaseEditorDocumentParser::Configuration parserConfig() const;
|
||||
|
||||
QFuture<CppEditor::CursorInfo> cursorInfo(const CppEditor::CursorInfoParams ¶ms) override;
|
||||
QFuture<CppEditor::CursorInfo> requestLocalReferences(const QTextCursor &cursor) override;
|
||||
@@ -115,6 +116,8 @@ public:
|
||||
|
||||
signals:
|
||||
void tokenInfosUpdated();
|
||||
void parserConfigChanged(const Utils::FilePath &filePath,
|
||||
const CppEditor::BaseEditorDocumentParser::Configuration &config);
|
||||
|
||||
private:
|
||||
void onParserFinished();
|
||||
|
||||
@@ -218,7 +218,15 @@ bool ClangModelManagerSupport::supportsLocalUses(const TextEditor::TextDocument
|
||||
CppEditor::BaseEditorDocumentProcessor *ClangModelManagerSupport::createEditorDocumentProcessor(
|
||||
TextEditor::TextDocument *baseTextDocument)
|
||||
{
|
||||
return new ClangEditorDocumentProcessor(m_communicator, baseTextDocument);
|
||||
const auto processor = new ClangEditorDocumentProcessor(m_communicator, baseTextDocument);
|
||||
const auto handleConfigChange = [this](const Utils::FilePath &fp,
|
||||
const BaseEditorDocumentParser::Configuration &config) {
|
||||
if (const auto client = clientForFile(fp))
|
||||
client->updateParserConfig(fp, config);
|
||||
};
|
||||
connect(processor, &ClangEditorDocumentProcessor::parserConfigChanged,
|
||||
this, handleConfigChange);
|
||||
return processor;
|
||||
}
|
||||
|
||||
void ClangModelManagerSupport::onCurrentEditorChanged(Core::IEditor *editor)
|
||||
@@ -234,6 +242,8 @@ void ClangModelManagerSupport::onCurrentEditorChanged(Core::IEditor *editor)
|
||||
if (auto processor = ClangEditorDocumentProcessor::get(filePath.toString())) {
|
||||
processor->semanticRehighlight();
|
||||
processor->generateTaskHubIssues();
|
||||
if (const auto client = clientForFile(filePath))
|
||||
client->updateParserConfig(filePath, processor->parserConfig());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -343,16 +353,38 @@ void ClangModelManagerSupport::updateLanguageClient(
|
||||
if (!newProjectInfo || *newProjectInfo != *projectInfo)
|
||||
return;
|
||||
|
||||
const auto updateParserConfig = [client] {
|
||||
if (const auto editor = TextEditor::BaseTextEditor::currentTextEditor()) {
|
||||
if (!client->documentOpen(editor->textDocument()))
|
||||
return;
|
||||
const Utils::FilePath filePath = editor->textDocument()->filePath();
|
||||
if (const auto processor = ClangEditorDocumentProcessor::get(
|
||||
filePath.toString())) {
|
||||
const CppEditor::BaseEditorDocumentParser::Configuration config
|
||||
= processor->parserConfig();
|
||||
client->updateParserConfig(filePath, config);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Acquaint the client with all open C++ documents for this project.
|
||||
bool hasDocuments = false;
|
||||
for (TextEditor::BaseTextEditor * const editor : allCppEditors()) {
|
||||
if (!project->isKnownFile(editor->textDocument()->filePath()))
|
||||
const Utils::FilePath filePath = editor->textDocument()->filePath();
|
||||
if (!project->isKnownFile(filePath))
|
||||
continue;
|
||||
LanguageClientManager::openDocumentWithClient(editor->textDocument(), client);
|
||||
ClangEditorDocumentProcessor::clearTextMarks(editor->textDocument()->filePath());
|
||||
ClangEditorDocumentProcessor::clearTextMarks(filePath);
|
||||
hasDocuments = true;
|
||||
}
|
||||
|
||||
if (client->state() == Client::Initialized)
|
||||
updateParserConfig();
|
||||
else
|
||||
connect(client, &Client::initialized, client, updateParserConfig);
|
||||
connect(CppModelManager::instance(), &CppModelManager::projectPartsUpdated,
|
||||
client, updateParserConfig);
|
||||
|
||||
if (hasDocuments)
|
||||
return;
|
||||
|
||||
|
||||
@@ -675,6 +675,8 @@ void ClangdTestHighlighting::initTestCase()
|
||||
{
|
||||
ClangdTest::initTestCase();
|
||||
|
||||
connect(document("highlighting.cpp"), &TextDocument::ifdefedOutBlocksChanged, this,
|
||||
[this](const QList<BlockRange> &ranges) { m_ifdefedOutBlocks = ranges; });
|
||||
QTimer timer;
|
||||
timer.setSingleShot(true);
|
||||
QEventLoop loop;
|
||||
@@ -1380,6 +1382,17 @@ void ClangdTestHighlighting::test()
|
||||
QCOMPARE(result.kind, expectedKind);
|
||||
}
|
||||
|
||||
void ClangdTestHighlighting::testIfdefedOutBlocks()
|
||||
{
|
||||
QCOMPARE(m_ifdefedOutBlocks.size(), 3);
|
||||
QCOMPARE(m_ifdefedOutBlocks.at(0).first(), 12033);
|
||||
QCOMPARE(m_ifdefedOutBlocks.at(0).last(), 12050);
|
||||
QCOMPARE(m_ifdefedOutBlocks.at(1).first(), 13351);
|
||||
QCOMPARE(m_ifdefedOutBlocks.at(1).last(), 13364);
|
||||
QCOMPARE(m_ifdefedOutBlocks.at(2).first(), 13390);
|
||||
QCOMPARE(m_ifdefedOutBlocks.at(2).last(), 13402);
|
||||
}
|
||||
|
||||
|
||||
class Manipulator : public TextDocumentManipulatorInterface
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
#include <cppeditor/cpptoolstestcase.h>
|
||||
#include <coreplugin/find/searchresultitem.h>
|
||||
#include <texteditor/blockrange.h>
|
||||
#include <texteditor/codeassist/genericproposal.h>
|
||||
#include <texteditor/semantichighlighter.h>
|
||||
#include <utils/fileutils.h>
|
||||
@@ -141,9 +142,11 @@ private slots:
|
||||
void initTestCase() override;
|
||||
void test_data();
|
||||
void test();
|
||||
void testIfdefedOutBlocks();
|
||||
|
||||
private:
|
||||
TextEditor::HighlightingResults m_results;
|
||||
QList<TextEditor::BlockRange> m_ifdefedOutBlocks;
|
||||
};
|
||||
|
||||
class ClangdTestCompletion : public ClangdTest
|
||||
|
||||
@@ -869,3 +869,14 @@ void constMemberAsFunctionArg()
|
||||
const Foo &constMember;
|
||||
};
|
||||
}
|
||||
|
||||
# if 0
|
||||
#define FOO
|
||||
|
||||
#endif
|
||||
|
||||
// comment
|
||||
|
||||
#if 0
|
||||
#define BAR
|
||||
# endif
|
||||
|
||||
Reference in New Issue
Block a user