From c1f05d58b8402ce3a96c524d960ecbf260b8d74a Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Fri, 26 Feb 2021 10:16:26 +0100 Subject: [PATCH] CppTools: Clear outdated "semantic parentheses" For instance, if the user types "template<", then the next operator> in the source code will be temporarily classified as the closing angle bracket for that template. Therefore, we have to clear out any previous information of that kind. Change-Id: Ib6d64415b2f6294661e2b8ec48cbaea5893d8fd0 Reviewed-by: David Schulz --- src/plugins/cpptools/semantichighlighter.cpp | 48 ++++++++++++++++++-- src/plugins/texteditor/textdocumentlayout.h | 3 ++ 2 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/plugins/cpptools/semantichighlighter.cpp b/src/plugins/cpptools/semantichighlighter.cpp index df40dce813d..d4d250166ca 100644 --- a/src/plugins/cpptools/semantichighlighter.cpp +++ b/src/plugins/cpptools/semantichighlighter.cpp @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -45,6 +46,8 @@ static Q_LOGGING_CATEGORY(log, "qtc.cpptools.semantichighlighter", QtWarningMsg) namespace CppTools { +static Utils::Id parenSource() { return "CppTools"; } + static const QList> splitRawStringLiteral(const HighlightingResult &result, const QTextBlock &startBlock) { @@ -147,6 +150,13 @@ void SemanticHighlighter::run() m_watcher->setFuture(m_highlightingRunner()); } +static Parentheses getClearedParentheses(const QTextBlock &block) +{ + return Utils::filtered(TextDocumentLayout::parentheses(block), [](const Parenthesis &p) { + return p.source != parenSource(); + }); +} + void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) { if (documentRevision() != m_revision) @@ -169,6 +179,9 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) const HighlightingResult &result = m_watcher->future().resultAt(i); if (result.kind != AngleBracketOpen && result.kind != AngleBracketClose && result.kind != TernaryIf && result.kind != TernaryElse) { + const QTextBlock block = + m_baseTextDocument->document()->findBlockByNumber(result.line - 1); + TextDocumentLayout::setParentheses(block, getClearedParentheses(block)); continue; } if (parentheses.first.isValid() && result.line - 1 > parentheses.first.blockNumber()) { @@ -177,16 +190,20 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to) } if (!parentheses.first.isValid()) { parentheses.first = m_baseTextDocument->document()->findBlockByNumber(result.line - 1); - parentheses.second = TextDocumentLayout::parentheses(parentheses.first); + parentheses.second = getClearedParentheses(parentheses.first); } + Parenthesis paren; if (result.kind == AngleBracketOpen) - parentheses.second << Parenthesis(Parenthesis::Opened, '<', result.column - 1); + paren = {Parenthesis::Opened, '<', result.column - 1}; else if (result.kind == AngleBracketClose) - parentheses.second << Parenthesis(Parenthesis::Closed, '>', result.column - 1); + paren = {Parenthesis::Closed, '>', result.column - 1}; else if (result.kind == TernaryIf) - parentheses.second << Parenthesis(Parenthesis::Opened, '?', result.column - 1); + paren = {Parenthesis::Opened, '?', result.column - 1}; else if (result.kind == TernaryElse) - parentheses.second << Parenthesis(Parenthesis::Closed, ':', result.column - 1); + paren = {Parenthesis::Closed, ':', result.column - 1}; + QTC_ASSERT(paren.pos != -1, continue); + paren.source = parenSource(); + parentheses.second << paren; } if (parentheses.first.isValid()) TextDocumentLayout::setParentheses(parentheses.first, parentheses.second); @@ -202,6 +219,27 @@ void SemanticHighlighter::onHighlighterFinished() clearExtraAdditionalFormatsUntilEnd(highlighter, m_watcher->future()); } } + + // Clear out previous "semantic parentheses". + QTextBlock firstResultBlock; + QTextBlock lastResultBlock; + if (m_watcher->future().resultCount() == 0) { + firstResultBlock = lastResultBlock = m_baseTextDocument->document()->lastBlock(); + } else { + firstResultBlock = m_baseTextDocument->document()->findBlockByNumber( + m_watcher->resultAt(0).line - 1); + lastResultBlock = m_baseTextDocument->document()->findBlockByNumber( + m_watcher->future().resultAt(m_watcher->future().resultCount() - 1).line - 1); + } + for (QTextBlock currentBlock = m_baseTextDocument->document()->firstBlock(); + currentBlock != firstResultBlock; currentBlock = currentBlock.next()) { + TextDocumentLayout::setParentheses(currentBlock, getClearedParentheses(currentBlock)); + } + for (QTextBlock currentBlock = lastResultBlock.next(); currentBlock.isValid(); + currentBlock = currentBlock.next()) { + TextDocumentLayout::setParentheses(currentBlock, getClearedParentheses(currentBlock)); + } + m_watcher.reset(); } diff --git a/src/plugins/texteditor/textdocumentlayout.h b/src/plugins/texteditor/textdocumentlayout.h index 7097d684c3b..776552a7efd 100644 --- a/src/plugins/texteditor/textdocumentlayout.h +++ b/src/plugins/texteditor/textdocumentlayout.h @@ -30,6 +30,8 @@ #include "textmark.h" #include "textdocument.h" +#include + #include #include @@ -48,6 +50,7 @@ struct TEXTEDITOR_EXPORT Parenthesis : pos(position), chr(c), type(t) {} int pos = -1; QChar chr; + Utils::Id source; Type type = Opened; };