forked from qt-creator/qt-creator
CppEditor: Add syntax highlighting for C++ attributes
Fixes: QTCREATORBUG-31241 Change-Id: I7583c3cd08c2ec58ca7702e7758aad6c0e142574 Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
<style name="Function"/>
|
||||
<style name="Macro"/>
|
||||
<style name="Keyword" foreground="#45c6d6" italic="true"/>
|
||||
<style name="Attribute" foreground="#45c6d6" italic="true"/>
|
||||
<style name="PrimitiveType" foreground="#d69aa7"/>
|
||||
<style name="Punctuation"/>
|
||||
<style name="Operator" foreground="#d6bb9a"/>
|
||||
|
@@ -19,6 +19,7 @@
|
||||
<style name="Macro"/>
|
||||
<style name="Global"/>
|
||||
<style name="Keyword" foreground="#ffff55"/>
|
||||
<style name="Attribute" foreground="#ffff55"/>
|
||||
<style name="PrimitiveType" foreground="#ffff55"/>
|
||||
<style name="Label" foreground="#ffff55"/>
|
||||
<style name="LineNumber" foreground="#888888" background="#232323"/>
|
||||
|
@@ -25,6 +25,7 @@
|
||||
<style name="Function" background="#ffffff"/>
|
||||
<style name="Macro" background="#ffffff"/>
|
||||
<style name="Keyword" foreground="#808000"/>
|
||||
<style name="Attribute" foreground="#808000"/>
|
||||
<style name="PrimitiveType" foreground="#808000"/>
|
||||
<style name="Punctuation"/>
|
||||
<style name="Operator"/>
|
||||
|
@@ -17,6 +17,7 @@
|
||||
<style name="Function"/>
|
||||
<style name="Macro"/>
|
||||
<style name="Keyword" bold="true"/>
|
||||
<style name="Attribute" bold="true"/>
|
||||
<style name="PrimitiveType" bold="true"/>
|
||||
<style name="Label"/>
|
||||
<style name="LineNumber" foreground="#c7c4c1" background="#efebe7"/>
|
||||
|
@@ -23,6 +23,7 @@
|
||||
<style name="Macro"/>
|
||||
<style name="Global"/>
|
||||
<style name="Keyword" foreground="#808bed"/>
|
||||
<style name="Attribute" foreground="#808bed"/>
|
||||
<style name="PrimitiveType" foreground="#808bed"/>
|
||||
<style name="Label" foreground="#e76000"/>
|
||||
<style name="LineNumber" foreground="#8b8bcd" background="#2e2e2e"/>
|
||||
|
@@ -11,6 +11,7 @@
|
||||
<style name="Function" foreground="#000000"/>
|
||||
<style name="Macro" foreground="#000000"/>
|
||||
<style name="Keyword" foreground="#000080" bold="true"/>
|
||||
<style name="Attribute" foreground="#000080" bold="true"/>
|
||||
<style name="PrimitiveType" foreground="#000080" bold="true"/>
|
||||
<style name="Label" foreground="#800000" bold="true"/>
|
||||
<style name="Local" foreground="#000000"/>
|
||||
|
@@ -35,6 +35,7 @@
|
||||
<style name="Function"/>
|
||||
<style name="Macro"/>
|
||||
<style name="Keyword" foreground="#78d7ec" italic="true"/>
|
||||
<style name="Attribute" foreground="#78d7ec" italic="true"/>
|
||||
<style name="PrimitiveType" foreground="#ff8080"/>
|
||||
<style name="Punctuation"/>
|
||||
<style name="Operator" foreground="#a6e22e"/>
|
||||
|
@@ -35,6 +35,7 @@
|
||||
<style name="Function" foreground="#839496"/>
|
||||
<style name="Macro" foreground="#839496"/>
|
||||
<style name="Keyword" foreground="#709d06"/>
|
||||
<style name="Attribute" foreground="#709d06"/>
|
||||
<style name="PrimitiveType" foreground="#808000"/>
|
||||
<style name="Punctuation"/>
|
||||
<style name="Operator" foreground="#839496"/>
|
||||
|
@@ -35,6 +35,7 @@
|
||||
<style name="Function" foreground="#657b83"/>
|
||||
<style name="Macro" foreground="#657b83"/>
|
||||
<style name="Keyword" foreground="#709d06"/>
|
||||
<style name="Attribute" foreground="#709d06"/>
|
||||
<style name="PrimitiveType" foreground="#808000"/>
|
||||
<style name="Punctuation"/>
|
||||
<style name="Operator" foreground="#657b83"/>
|
||||
|
@@ -33,6 +33,15 @@ using namespace CPlusPlus;
|
||||
namespace CppEditor {
|
||||
using namespace Internal;
|
||||
|
||||
union AttributeState {
|
||||
struct {
|
||||
quint8 lbrackets: 1;
|
||||
quint8 rbrackets: 1;
|
||||
quint8 opened: 6;
|
||||
};
|
||||
quint8 state;
|
||||
};
|
||||
|
||||
CppHighlighter::CppHighlighter(QTextDocument *document) :
|
||||
SyntaxHighlighter(document)
|
||||
{
|
||||
@@ -79,6 +88,8 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
userData->setFoldingStartIncluded(false);
|
||||
userData->setFoldingEndIncluded(false);
|
||||
}
|
||||
AttributeState attrState;
|
||||
attrState.state = TextDocumentLayout::attributeState(prevBlock);
|
||||
|
||||
if (tokens.isEmpty()) {
|
||||
setCurrentBlockState((braceDepth << 8) | lexerState);
|
||||
@@ -93,6 +104,7 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
}
|
||||
TextDocumentLayout::setFoldingIndent(currentBlock(), foldingIndent);
|
||||
TextDocumentLayout::setExpectedRawStringSuffix(currentBlock(), inheritedRawStringSuffix);
|
||||
TextDocumentLayout::setAttributeState(currentBlock(), attrState.state);
|
||||
qCDebug(highlighterLog) << "no tokens, storing brace depth" << braceDepth << "and foldingIndent"
|
||||
<< foldingIndent;
|
||||
return;
|
||||
@@ -185,6 +197,25 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
if (onlyHighlightComments && !tk.isComment())
|
||||
continue;
|
||||
|
||||
// Handle attributes, i.e. identifiers in pairs of "[[" and "]]".
|
||||
if (tk.is(T_LBRACKET) && !tk.isOperator()) {
|
||||
attrState.lbrackets = !attrState.lbrackets;
|
||||
if (attrState.lbrackets == 0)
|
||||
++attrState.opened;
|
||||
continue;
|
||||
}
|
||||
if (tk.is(T_RBRACKET) && !tk.isOperator()) {
|
||||
attrState.rbrackets = !attrState.rbrackets;
|
||||
if (attrState.rbrackets == 0 && attrState.opened > 0)
|
||||
--attrState.opened;
|
||||
continue;
|
||||
}
|
||||
attrState.lbrackets = attrState.rbrackets = 0;
|
||||
if (attrState.opened && (tk.is(T_IDENTIFIER) || (tk.isKeyword() && !tk.is(T_USING)))) {
|
||||
setFormat(tk.utf16charsBegin(), tk.utf16chars(), formatForCategory(C_ATTRIBUTE));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i == 0 && tk.is(T_POUND)) {
|
||||
setFormatWithSpaces(text, tk.utf16charsBegin(), tk.utf16chars(),
|
||||
formatForCategory(C_PREPROCESSOR));
|
||||
@@ -297,6 +328,7 @@ void CppHighlighter::highlightBlock(const QString &text)
|
||||
}
|
||||
|
||||
TextDocumentLayout::setParentheses(currentBlock(), parentheses);
|
||||
TextDocumentLayout::setAttributeState(currentBlock(), attrState.state);
|
||||
|
||||
TextDocumentLayout::setFoldingIndent(currentBlock(), foldingIndent);
|
||||
setCurrentBlockState(rehighlightNextBlock | (braceDepth << 8) | tokenize.state());
|
||||
@@ -655,6 +687,46 @@ private slots:
|
||||
<< 73 << 17 << 73 << 18 << C_STRING;
|
||||
QTest::newRow("wide char literal with user-defined suffix (suffix)")
|
||||
<< 73 << 20 << 73 << 22 << C_OVERLOADED_OPERATOR;
|
||||
QTest::newRow("separate attributes specs, 1/4, namespace")
|
||||
<< 75 << 3 << 72 << 5 << C_ATTRIBUTE;
|
||||
QTest::newRow("separate attributes specs, 1/4, attr")
|
||||
<< 75 << 8 << 72 << 20 << C_ATTRIBUTE;
|
||||
QTest::newRow("separate attributes specs, 2/4, namespace")
|
||||
<< 75 << 26 << 72 << 28 << C_ATTRIBUTE;
|
||||
QTest::newRow("separate attributes specs, 2/4, attr")
|
||||
<< 75 << 31 << 72 << 33 << C_ATTRIBUTE;
|
||||
QTest::newRow("separate attributes specs, 3/4, namespace")
|
||||
<< 75 << 39 << 72 << 41 << C_ATTRIBUTE;
|
||||
QTest::newRow("separate attributes specs, 3/4, attr")
|
||||
<< 75 << 44 << 72 << 48 << C_ATTRIBUTE;
|
||||
QTest::newRow("separate attributes specs, 4/4, attr")
|
||||
<< 75 << 54 << 72 << 62 << C_ATTRIBUTE;
|
||||
QTest::newRow("single attributes spec, 1/4, namespace")
|
||||
<< 76 << 3 << 73 << 5 << C_ATTRIBUTE;
|
||||
QTest::newRow("single attributes spec, 1/4, attr")
|
||||
<< 76 << 8 << 73 << 20 << C_ATTRIBUTE;
|
||||
QTest::newRow("single attributes spec, 2/4, namespace")
|
||||
<< 76 << 23 << 73 << 25 << C_ATTRIBUTE;
|
||||
QTest::newRow("single attributes spec, 2/4, attr")
|
||||
<< 76 << 28 << 73 << 32 << C_ATTRIBUTE;
|
||||
QTest::newRow("single attributes spec, 3/4, namespace")
|
||||
<< 76 << 35 << 73 << 37 << C_ATTRIBUTE;
|
||||
QTest::newRow("single attributes spec, 3/4, attr")
|
||||
<< 76 << 40 << 73 << 42 << C_ATTRIBUTE;
|
||||
QTest::newRow("single attributes spec, 4/4, attr")
|
||||
<< 76 << 45 << 73 << 53 << C_ATTRIBUTE;
|
||||
QTest::newRow("attributes with using, namespace")
|
||||
<< 77 << 9 << 74 << 11 << C_ATTRIBUTE;
|
||||
QTest::newRow("attributes with using, attr 1/3")
|
||||
<< 77 << 15 << 74 << 19 << C_ATTRIBUTE;
|
||||
QTest::newRow("attributes with using, attr 2/3")
|
||||
<< 77 << 22 << 74 << 34 << C_ATTRIBUTE;
|
||||
QTest::newRow("attributes with using, attr 3/3")
|
||||
<< 77 << 37 << 74 << 39 << C_ATTRIBUTE;
|
||||
QTest::newRow("attribute with line split, namespace")
|
||||
<< 79 << 9 << 76 << 11 << C_ATTRIBUTE;
|
||||
QTest::newRow("attribute with line split, attr")
|
||||
<< 79 << 14 << 76 << 26 << C_ATTRIBUTE;
|
||||
}
|
||||
|
||||
void test()
|
||||
|
@@ -71,3 +71,10 @@ static void parenTest2()
|
||||
|
||||
wchar_t operator ""_wc(const wchar_t c) { return c; }
|
||||
const auto c = L'c'_wc;
|
||||
|
||||
[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]] int attr1();
|
||||
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]] int attr2();
|
||||
[[using gnu : const, always_inline, hot]] int attr3[
|
||||
[
|
||||
gnu::always_inline]
|
||||
]();
|
||||
|
@@ -543,6 +543,21 @@ TextSuggestion *TextDocumentLayout::suggestion(const QTextBlock &block)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TextDocumentLayout::setAttributeState(const QTextBlock &block, quint8 attrState)
|
||||
{
|
||||
if (TextBlockUserData * const data = textUserData(block))
|
||||
data->setAttrState(attrState);
|
||||
else if (attrState)
|
||||
userData(block)->setAttrState(attrState);
|
||||
}
|
||||
|
||||
quint8 TextDocumentLayout::attributeState(const QTextBlock &block)
|
||||
{
|
||||
if (TextBlockUserData *userData = textUserData(block))
|
||||
return userData->attrState();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TextDocumentLayout::updateSuggestionFormats(const QTextBlock &block,
|
||||
const FontSettings &fontSettings)
|
||||
{
|
||||
|
@@ -153,6 +153,9 @@ public:
|
||||
TextSuggestion *suggestion() const;
|
||||
void clearSuggestion();
|
||||
|
||||
void setAttrState(quint8 state) { m_attrState = state; }
|
||||
quint8 attrState() const { return m_attrState; }
|
||||
|
||||
private:
|
||||
TextMarks m_marks;
|
||||
int m_foldingIndent : 16;
|
||||
@@ -168,6 +171,7 @@ private:
|
||||
QByteArray m_expectedRawStringSuffix; // A bit C++-specific, but let's be pragmatic.
|
||||
std::unique_ptr<QTextDocument> m_replacement;
|
||||
std::unique_ptr<TextSuggestion> m_suggestion;
|
||||
quint8 m_attrState = 0;
|
||||
};
|
||||
|
||||
class TEXTEDITOR_EXPORT TextDocumentLayout : public QPlainTextDocumentLayout
|
||||
@@ -201,6 +205,8 @@ public:
|
||||
static void setExpectedRawStringSuffix(const QTextBlock &block, const QByteArray &suffix);
|
||||
static QByteArray expectedRawStringSuffix(const QTextBlock &block);
|
||||
static TextSuggestion *suggestion(const QTextBlock &block);
|
||||
static void setAttributeState(const QTextBlock &block, quint8 attrState);
|
||||
static quint8 attributeState(const QTextBlock &block);
|
||||
static void updateSuggestionFormats(const QTextBlock &block,
|
||||
const FontSettings &fontSettings);
|
||||
static bool updateSuggestion(const QTextBlock &block,
|
||||
|
@@ -52,6 +52,7 @@ const char *nameForStyle(TextStyle style)
|
||||
case C_PREPROCESSOR: return "Preprocessor";
|
||||
case C_MACRO: return "Macro";
|
||||
case C_LABEL: return "Label";
|
||||
case C_ATTRIBUTE: return "Attribute";
|
||||
case C_COMMENT: return "Comment";
|
||||
case C_DOXYGEN_COMMENT: return "Doxygen.Comment";
|
||||
case C_DOXYGEN_TAG: return "Doxygen.Tag";
|
||||
|
@@ -50,6 +50,7 @@ enum TextStyle : quint8 {
|
||||
C_PREPROCESSOR,
|
||||
C_MACRO,
|
||||
C_LABEL,
|
||||
C_ATTRIBUTE,
|
||||
C_COMMENT,
|
||||
C_DOXYGEN_COMMENT,
|
||||
C_DOXYGEN_TAG,
|
||||
|
@@ -251,6 +251,8 @@ FormatDescriptions TextEditorSettingsPrivate::initialFormats()
|
||||
Tr::tr("Macros."), functionFormat);
|
||||
formatDescr.emplace_back(C_LABEL, Tr::tr("Label"), Tr::tr("Labels for goto statements."),
|
||||
Qt::darkRed);
|
||||
formatDescr.emplace_back(C_ATTRIBUTE, Tr::tr("Attribute"), Tr::tr("Attributes."),
|
||||
Qt::darkYellow);
|
||||
formatDescr.emplace_back(C_COMMENT, Tr::tr("Comment"),
|
||||
Tr::tr("All style of comments except Doxygen comments."),
|
||||
Qt::darkGreen);
|
||||
|
Reference in New Issue
Block a user