forked from qt-creator/qt-creator
ClangCodeModel: Do not ignore highlighting for raw string literals
Also add the special handling for prefix and suffix like in CppHighlighter, as not to re-introduce QTCREATORBUG-19119. Fixes: QTCREATORBUG-16183 Change-Id: Ie264946782220a8e5a862c1d4550bcd49bc2349f Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -44,6 +44,69 @@ static Q_LOGGING_CATEGORY(log, "qtc.cpptools.semantichighlighter", QtWarningMsg)
|
||||
|
||||
namespace CppTools {
|
||||
|
||||
static const QList<std::pair<HighlightingResult, QTextBlock>>
|
||||
splitRawStringLiteral(const HighlightingResult &result, const QTextBlock &startBlock)
|
||||
{
|
||||
if (result.textStyles.mainStyle != C_STRING)
|
||||
return {{result, startBlock}};
|
||||
|
||||
QTextCursor cursor(startBlock);
|
||||
cursor.setPosition(cursor.position() + result.column - 1);
|
||||
cursor.setPosition(cursor.position() + result.length, QTextCursor::KeepAnchor);
|
||||
const QString theString = cursor.selectedText();
|
||||
|
||||
// Find all the components of a raw string literal. If we don't succeed, then it's
|
||||
// something else.
|
||||
if (!theString.endsWith('"'))
|
||||
return {{result, startBlock}};
|
||||
int rOffset = -1;
|
||||
if (theString.startsWith("R\"")) {
|
||||
rOffset = 0;
|
||||
} else if (theString.startsWith("LR\"")
|
||||
|| theString.startsWith("uR\"")
|
||||
|| theString.startsWith("UR\"")) {
|
||||
rOffset = 1;
|
||||
} else if (theString.startsWith("u8R\"")) {
|
||||
rOffset = 2;
|
||||
}
|
||||
if (rOffset == -1)
|
||||
return {{result, startBlock}};
|
||||
const int delimiterOffset = rOffset + 2;
|
||||
const int openParenOffset = theString.indexOf('(', delimiterOffset);
|
||||
if (openParenOffset == -1)
|
||||
return {{result, startBlock}};
|
||||
const QStringView delimiter = theString.mid(delimiterOffset, openParenOffset - delimiterOffset);
|
||||
const int endDelimiterOffset = theString.length() - 1 - delimiter.length();
|
||||
if (theString.mid(endDelimiterOffset, delimiter.length()) != delimiter)
|
||||
return {{result, startBlock}};
|
||||
if (theString.at(endDelimiterOffset - 1) != ')')
|
||||
return {{result, startBlock}};
|
||||
|
||||
// Now split the result. For clarity, we display only the actual content as a string,
|
||||
// and the rest (including the delimiter) as a keyword.
|
||||
HighlightingResult prefix = result;
|
||||
prefix.textStyles.mainStyle = C_KEYWORD;
|
||||
prefix.textStyles.mixinStyles = {};
|
||||
prefix.length = delimiterOffset + delimiter.length() + 1;
|
||||
cursor.setPosition(startBlock.position() + result.column - 1 + prefix.length);
|
||||
QTextBlock stringBlock = cursor.block();
|
||||
HighlightingResult actualString = result;
|
||||
actualString.line = stringBlock.blockNumber() + 1;
|
||||
actualString.column = cursor.positionInBlock() + 1;
|
||||
actualString.length = endDelimiterOffset - openParenOffset - 2;
|
||||
cursor.setPosition(cursor.position() + actualString.length);
|
||||
QTextBlock suffixBlock = cursor.block();
|
||||
HighlightingResult suffix = result;
|
||||
suffix.textStyles.mainStyle = C_KEYWORD;
|
||||
suffix.textStyles.mixinStyles = {};
|
||||
suffix.line = suffixBlock.blockNumber() + 1;
|
||||
suffix.column = cursor.positionInBlock() + 1;
|
||||
suffix.length = delimiter.length() + 2;
|
||||
QTC_CHECK(prefix.length + actualString.length + suffix.length == result.length);
|
||||
|
||||
return {{prefix, startBlock}, {actualString, stringBlock}, {suffix, suffixBlock}};
|
||||
}
|
||||
|
||||
SemanticHighlighter::SemanticHighlighter(TextDocument *baseTextDocument)
|
||||
: QObject(baseTextDocument)
|
||||
, m_baseTextDocument(baseTextDocument)
|
||||
@@ -94,7 +157,8 @@ void SemanticHighlighter::onHighlighterResultAvailable(int from, int to)
|
||||
|
||||
SyntaxHighlighter *highlighter = m_baseTextDocument->syntaxHighlighter();
|
||||
QTC_ASSERT(highlighter, return);
|
||||
incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap);
|
||||
incrementalApplyExtraAdditionalFormats(highlighter, m_watcher->future(), from, to, m_formatMap,
|
||||
&splitRawStringLiteral);
|
||||
}
|
||||
|
||||
void SemanticHighlighter::onHighlighterFinished()
|
||||
|
||||
Reference in New Issue
Block a user