From e72b780dc38138bc2f055c39272ff597af5edb26 Mon Sep 17 00:00:00 2001 From: Roy Qu Date: Thu, 21 Mar 2024 21:28:12 +0800 Subject: [PATCH] - enhancement: Syntax highlighting for c++ attributes. fix: mingw build errors --- NEWS.md | 1 + RedPandaIDE/mainwindow.cpp | 1 + libs/qsynedit/qsynedit/syntaxer/cpp.cpp | 59 ++++++++++++++++++---- libs/qsynedit/qsynedit/syntaxer/cpp.h | 3 ++ libs/qsynedit/qsynedit/syntaxer/syntaxer.h | 4 +- 5 files changed, 57 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index 82ff23dc..432b0bc4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -73,6 +73,7 @@ Red Panda C++ Version 2.27 - fix: Option 'Pause after run in console' for tools doesn't work. - fix: Filename that contains '&' doesn't correctly displayed in the editor tab. - enhancement: Type induction for "auto &&" vars. + - enhancement: Syntax highlighting for c++ attributes. Red Panda C++ Version 2.26 - enhancement: Code suggestion for embedded std::vectors. diff --git a/RedPandaIDE/mainwindow.cpp b/RedPandaIDE/mainwindow.cpp index f765d7c2..0212e155 100644 --- a/RedPandaIDE/mainwindow.cpp +++ b/RedPandaIDE/mainwindow.cpp @@ -86,6 +86,7 @@ #include #include #include +#include #include "mainwindow.h" #include diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp index 2617ca7f..e26cad7e 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.cpp +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.cpp @@ -20,6 +20,9 @@ #include #include +#define DATA_KEY_INITIAL_DCHAR_SEQ "initialDCharSeq" +#define DATA_KEY_IN_ATTRIBUTE "inAttribute" + namespace QSynedit { static const QSet CppStatementKeyWords { @@ -152,6 +155,21 @@ const QSet CppSyntaxer::Keywords { "nullptr", }; + +const QSet CppSyntaxer::StandardAttributes { + "noreturn", + "carries_dependency", + "deprecated", + "fallthrough", + "nodiscard", + "maybe_unused", + "likely", + "unlikely", + "no_unique_address", + "assume", + "optimize_for_synchronized" +}; + CppSyntaxer::CppSyntaxer(): Syntaxer() { mCharAttribute = std::make_shared(SYNS_AttrCharacter, @@ -293,6 +311,12 @@ bool CppSyntaxer::isCharEscaping(int state) return state == RangeState::rsCharEscaping; } +bool CppSyntaxer::isInAttribute(const SyntaxState &state) +{ + return state.extraData.contains(DATA_KEY_IN_ATTRIBUTE) + && state.extraData[DATA_KEY_IN_ATTRIBUTE].toBool(); +} + CppSyntaxer::TokenId CppSyntaxer::getTokenId() { return mTokenId; @@ -652,6 +676,8 @@ void CppSyntaxer::procIdentifier() if (CppStatementKeyWords.contains(word)) { pushIndents(IndentType::Statement); } + } else if (isInAttribute(mRange) && StandardAttributes.contains(word)) { + mTokenId = TokenId::Key; } else { mTokenId = TokenId::Identifier; } @@ -1002,7 +1028,7 @@ void CppSyntaxer::procRawString() mTokenId = TokenId::RawString; QString rawStringInitialDCharSeq; if (mRange.state == RangeState::rsRawString) - mRange.extraData = std::make_shared(""); + mRange.extraData[DATA_KEY_INITIAL_DCHAR_SEQ] = ""; while (mRun(rawStringInitialDCharSeq); + mRange.extraData[DATA_KEY_INITIAL_DCHAR_SEQ] = rawStringInitialDCharSeq; } break; case ')': if (mRange.state == RangeState::rsRawStringNotEscaping) { - rawStringInitialDCharSeq = mRange.extraData->toString(); + rawStringInitialDCharSeq = mRange.extraData[DATA_KEY_INITIAL_DCHAR_SEQ].toString(); if ( mLine.mid(mRun+1,rawStringInitialDCharSeq.length()) == rawStringInitialDCharSeq) { mRun = mRun+rawStringInitialDCharSeq.length(); mRange.state = RangeState::rsRawStringEnd; - mRange.extraData = nullptr; + mRange.extraData.remove(DATA_KEY_INITIAL_DCHAR_SEQ); } } break; @@ -1137,7 +1163,16 @@ void CppSyntaxer::procSpace() void CppSyntaxer::procSquareClose() { - mRun+=1; + mRun++; + if (mRun < mLineSize && mLine[mRun]==']') { + if (mRange.extraData.contains(DATA_KEY_IN_ATTRIBUTE) + && mRange.extraData[DATA_KEY_IN_ATTRIBUTE].toBool()) { + mTokenId = TokenId::Symbol; + mRun++; + mRange.extraData.remove(DATA_KEY_IN_ATTRIBUTE); + return; + } + } mTokenId = TokenId::Symbol; mRange.bracketLevel--; if (mRange.bracketLevel<0) @@ -1147,10 +1182,16 @@ void CppSyntaxer::procSquareClose() void CppSyntaxer::procSquareOpen() { - mRun+=1; - mTokenId = TokenId::Symbol; - mRange.bracketLevel++; - pushIndents(IndentType::Bracket); + mRun++; + if (mRun < mLineSize && mLine[mRun]=='[') { + mRun++; + mTokenId = TokenId::Symbol; + mRange.extraData[DATA_KEY_IN_ATTRIBUTE]=true; + } else{ + mTokenId = TokenId::Symbol; + mRange.bracketLevel++; + pushIndents(IndentType::Bracket); + } } void CppSyntaxer::procStar() diff --git a/libs/qsynedit/qsynedit/syntaxer/cpp.h b/libs/qsynedit/qsynedit/syntaxer/cpp.h index 6209da37..2235fafa 100644 --- a/libs/qsynedit/qsynedit/syntaxer/cpp.h +++ b/libs/qsynedit/qsynedit/syntaxer/cpp.h @@ -90,12 +90,15 @@ public: static const QSet ValidIntegerSuffixes; + static const QSet StandardAttributes; + bool isStringToNextLine(int state); bool isRawStringStart(int state); bool isRawStringNoEscape(int state); bool isRawStringEnd(int state); bool isCharNotFinished(int state); bool isCharEscaping(int state); + bool isInAttribute(const SyntaxState &state); TokenId getTokenId(); private: diff --git a/libs/qsynedit/qsynedit/syntaxer/syntaxer.h b/libs/qsynedit/qsynedit/syntaxer/syntaxer.h index 08417146..dcb7e8f0 100644 --- a/libs/qsynedit/qsynedit/syntaxer/syntaxer.h +++ b/libs/qsynedit/qsynedit/syntaxer/syntaxer.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include "../types.h" namespace QSynedit { @@ -57,7 +57,7 @@ struct SyntaxState { QVector indents; // indents stack (needed by auto indent) IndentInfo lastUnindent; bool hasTrailingSpaces; - std::shared_ptr extraData; + QMap extraData; bool operator==(const SyntaxState& s2); IndentInfo getLastIndent();