aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/cppeditor/cpphighlighter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/cppeditor/cpphighlighter.cpp')
-rw-r--r--src/plugins/cppeditor/cpphighlighter.cpp53
1 files changed, 51 insertions, 2 deletions
diff --git a/src/plugins/cppeditor/cpphighlighter.cpp b/src/plugins/cppeditor/cpphighlighter.cpp
index d862ea3c2c..3b7827d211 100644
--- a/src/plugins/cppeditor/cpphighlighter.cpp
+++ b/src/plugins/cppeditor/cpphighlighter.cpp
@@ -164,7 +164,10 @@ void CppHighlighter::highlightBlock(const QString &text)
} else if (tk.is(T_NUMERIC_LITERAL)) {
setFormat(tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_NUMBER));
} else if (tk.isStringLiteral() || tk.isCharLiteral()) {
- setFormatWithSpaces(text, tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_STRING));
+ if (!highlightRawStringLiteral(text, tk)) {
+ setFormatWithSpaces(text, tk.utf16charsBegin(), tk.utf16chars(),
+ formatForCategory(C_STRING));
+ }
} else if (tk.isComment()) {
const int startPosition = initialLexerState ? previousTokenEnd : tk.utf16charsBegin();
if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT)) {
@@ -195,7 +198,7 @@ void CppHighlighter::highlightBlock(const QString &text)
} else if (tk.isKeyword()
|| (m_languageFeatures.qtKeywordsEnabled
- && CppTools::isQtKeyword(text.midRef(tk.utf16charsBegin(), tk.utf16chars())))
+ && CppTools::isQtKeyword(QStringView{text}.mid(tk.utf16charsBegin(), tk.utf16chars())))
|| (m_languageFeatures.objCEnabled && tk.isObjCAtKeyword())) {
setFormat(tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_KEYWORD));
} else if (tk.isPrimitiveType()) {
@@ -363,6 +366,52 @@ void CppHighlighter::highlightWord(QStringRef word, int position, int length)
}
}
+bool CppHighlighter::highlightRawStringLiteral(const QStringView &_text, const Token &tk)
+{
+ // Step one: Does the lexer think this is a raw string literal?
+ switch (tk.kind()) {
+ case T_RAW_STRING_LITERAL:
+ case T_RAW_WIDE_STRING_LITERAL:
+ case T_RAW_UTF8_STRING_LITERAL:
+ case T_RAW_UTF16_STRING_LITERAL:
+ case T_RAW_UTF32_STRING_LITERAL:
+ break;
+ default:
+ return false;
+ }
+
+ // TODO: Remove on upgrade to Qt >= 5.14.
+ const QString text = _text.toString();
+
+ // Step two: Find all the components. Bail out if we don't have a complete,
+ // well-formed raw string literal.
+ const int rOffset = text.indexOf(QLatin1String("R\""), tk.utf16charsBegin());
+ if (rOffset == -1)
+ return false;
+ const int delimiterOffset = rOffset + 2;
+ const int openParenOffset = text.indexOf('(', delimiterOffset);
+ if (openParenOffset == -1)
+ return false;
+ const QStringView delimiter = text.mid(delimiterOffset, openParenOffset - delimiterOffset);
+ if (text.at(tk.utf16charsEnd() - 1) != '"')
+ return false;
+ const int endDelimiterOffset = tk.utf16charsEnd() - 1 - delimiter.length();
+ if (text.mid(endDelimiterOffset, delimiter.length()) != delimiter)
+ return false;
+ if (text.at(endDelimiterOffset - 1) != ')')
+ return false;
+
+ // Step three: Do the actual formatting. For clarity, we display only the actual content as
+ // a string, and the rest (including the delimiter) as a keyword.
+ const QTextCharFormat delimiterFormat = formatForCategory(C_KEYWORD);
+ const int stringOffset = delimiterOffset + delimiter.length() + 1;
+ setFormat(tk.utf16charsBegin(), stringOffset, delimiterFormat);
+ setFormatWithSpaces(text, stringOffset, endDelimiterOffset - stringOffset - 1,
+ formatForCategory(C_STRING));
+ setFormat(endDelimiterOffset - 1, delimiter.length() + 2, delimiterFormat);
+ return true;
+}
+
void CppHighlighter::highlightDoxygenComment(const QString &text, int position, int)
{
int initial = position;