diff --git a/lexilla/lexers_x/CharSetX.h b/lexilla/lexers_x/CharSetX.h index 3473ec213..7a4bddbd5 100644 --- a/lexilla/lexers_x/CharSetX.h +++ b/lexilla/lexers_x/CharSetX.h @@ -55,11 +55,9 @@ constexpr bool IsWhiteSpace(const int ch) noexcept return Lexilla::isspacechar(ch); } -constexpr bool IsAHexDigit(int ch) noexcept +constexpr bool IsHexDigit(int ch) noexcept { - return ((ch >= '0') && (ch <= '9')) - || ((ch >= 'A') && (ch <= 'F')) - || ((ch >= 'a') && (ch <= 'f')); + return Lexilla::IsAHeXDigit(ch); } constexpr bool IsALetter(const int ch) noexcept @@ -68,9 +66,31 @@ constexpr bool IsALetter(const int ch) noexcept return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); } -constexpr bool IsNewline(const int ch) { +constexpr bool IsEOLChar(const int ch) noexcept +{ + return (ch == '\n' || ch == '\r'); +} + +constexpr bool IsNewline(const int ch) noexcept +{ // sc.GetRelative(i) returns '\0' if out of range - return (ch == '\n' || ch == '\r' || ch == '\0'); + return IsEOLChar(ch) || (ch == '\0'); +} + +constexpr bool IsAGraphic(int ch) noexcept +{ + // excludes C0 control characters and whitespace + return ch > 32 && ch < 127; +} + +constexpr bool IsGraphic(int ch) noexcept +{ + // excludes C0 control characters and whitespace + return ch > 32 && ch != 127; +} + +constexpr bool IsJumpLabelPrevChar(int chPrev) noexcept { + return chPrev == ';' || chPrev == '{' || chPrev == '}'; } constexpr bool IsLineEndUTF8(const unsigned char ch0, diff --git a/lexilla/lexers_x/LexDart.cxx b/lexilla/lexers_x/LexDart.cxx index 3da34552d..b80650f4e 100644 --- a/lexilla/lexers_x/LexDart.cxx +++ b/lexilla/lexers_x/LexDart.cxx @@ -52,7 +52,6 @@ struct OptionsDart static const char* const dartWordLists[] = { "Keywords", - "Keywords2", "Types", "Classes", "Enums", @@ -95,8 +94,6 @@ LexicalClass lexicalClasses[] = SCE_DART_RAWSTRING_DQ, "SCE_DART_RAWSTRING_DQ", "rawstrg_dq", "Descr", SCE_DART_TRIPLE_RAWSTRING_SQ, "SCE_DART_TRIPLE_RAWSTRING_SQ", "trirawstrg_sq", "Descr", SCE_DART_TRIPLE_RAWSTRING_DQ, "SCE_DART_TRIPLE_RAWSTRING_DQ", "trirawstrg_dq", "Descr", - SCE_DART_TRIPLE_STRINGSTART, "SCE_DART_TRIPLE_STRINGSTART", "string_beg", "Descr", - SCE_DART_TRIPLE_STRINGEND, "SCE_DART_TRIPLE_STRINGEND", "string_end", "Descr", SCE_DART_SYMBOL_OPERATOR, "SCE_DART_SYMBOL_OPERATOR", "sym_operator", "Descr", SCE_DART_SYMBOL_IDENTIFIER, "SCE_DART_SYMBOL_IDENTIFIER", "sym_identifier", "Descr", SCE_DART_VARIABLE, "SCE_DART_VARIABLE", "variable", "Descr", @@ -121,13 +118,7 @@ class LexerDart : public DefaultLexer //CharacterSet validNumberEnd; //CharacterSet chDateTime; - WordList wl_keywords; - WordList wl_keywords2; - WordList wl_types; - WordList wl_classes; - WordList wl_enums; - WordList wl_metadata; - WordList wl_functions; + WordList keywordLists[KEYWORDSET_MAX + 1]; OptionsDart options; OptionSetDart osDart; @@ -141,7 +132,7 @@ public: //, chDateTime(CharacterSet::setNone, "-+.:TZ", 0x80, false) { } - virtual ~LexerDart() { } + virtual ~LexerDart() = default; void SCI_METHOD Release() override { @@ -217,35 +208,18 @@ Sci_Position SCI_METHOD LexerDart::PropertySet(const char* key, const char* val) return -1; } +enum { + KeywordIndex_Keyword = 0, + KeywordIndex_Type = 1, + KeywordIndex_Class = 2, + KeywordIndex_Enumeration = 3, + KeywordIndex_MetaData = 4, + KeywordIndex_Function = 5 +}; Sci_Position SCI_METHOD LexerDart::WordListSet(int n, const char* wl) { - WordList* wordListN = nullptr; - - switch (n) - { - case 0: - wordListN = &wl_keywords; - break; - case 1: - wordListN = &wl_keywords2; - break; - case 2: - wordListN = &wl_types; - break; - case 3: - wordListN = &wl_classes; - break; - case 4: - wordListN = &wl_enums; - break; - case 5: - wordListN = &wl_metadata; - break; - case 6: - wordListN = &wl_functions; - break; - } + WordList* wordListN = &(keywordLists[n]); Sci_Position firstModification = -1LL; if (wordListN) { @@ -261,32 +235,45 @@ Sci_Position SCI_METHOD LexerDart::WordListSet(int n, const char* wl) struct EscapeSequence { int outerState = SCE_DART_DEFAULT; int digitsLeft = 0; + bool brace = false; - // highlight any character as escape sequence, no highlight for hex in '\u{hex}'. + // highlight any character as escape sequence. bool resetEscapeState(int state, int chNext) noexcept { + if (IsNewline(chNext)) { + return false; + } outerState = state; + brace = false; digitsLeft = (chNext == 'x') ? 3 : ((chNext == 'u') ? 5 : 1); return true; } bool atEscapeEnd(int ch) noexcept { --digitsLeft; - return digitsLeft <= 0 || !IsAHexDigit(ch); + return digitsLeft <= 0 || !IsHexDigit(ch); } }; - enum { DartLineStateMaskLineComment = 1, // line comment DartLineStateMaskImport = (1 << 1), // import }; +enum class KeywordType { + None = SCE_DART_DEFAULT, + Class = SCE_DART_CLASS, + Enum = SCE_DART_ENUM, + Label = SCE_DART_LABEL, + Return = 0x40, + While, +}; + static_assert(DefaultNestedStateBaseStyle + 1 == SCE_DART_STRING_SQ); static_assert(DefaultNestedStateBaseStyle + 2 == SCE_DART_STRING_DQ); static_assert(DefaultNestedStateBaseStyle + 3 == SCE_DART_TRIPLE_STRING_SQ); static_assert(DefaultNestedStateBaseStyle + 4 == SCE_DART_TRIPLE_STRING_DQ); constexpr bool IsDeclarableOperator(int ch) noexcept { - // https://github.com/dart-lang/sdk/blob/master/sdk/lib/core/symbol.dart + // https://github.com/dart-lang/sdk/blob/main/sdk/lib/core/symbol.dart return AnyOf(ch, '+', '-', '*', '/', '%', '~', '&', '|', '^', '<', '>', '=', '[', ']'); } @@ -295,26 +282,39 @@ constexpr bool IsSpaceEquiv(int state) noexcept { return state <= SCE_DART_TASKMARKER; } +constexpr bool IsTripleString(int state) noexcept { + return ((state - SCE_DART_STRING_SQ) & 3) > 1; +} +constexpr int GetStringQuote(int state) noexcept { + if constexpr (SCE_DART_STRING_SQ & 1) { + return (state & 1) ? '\'' : '\"'; + } else { + return (state & 1) ? '\"' : '\''; + } +} void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument* pAccess) { PropSetSimple props; Accessor styler(pAccess, &props); - StyleContext sc(startPos, lengthDoc, initStyle, styler); int lineStateLineType = 0; int commentLevel = 0; // nested block comment level - int kwType = SCE_DART_DEFAULT; + KeywordType kwType = KeywordType::None; int chBeforeIdentifier = 0; std::vector nestedState; // string interpolation "${}" int visibleChars = 0; + int chBefore = 0; int visibleCharsBefore = 0; + int chPrevNonWhite = 0; + bool simpleStringInterpolation = false; EscapeSequence escSeq; + StyleContext sc(startPos, lengthDoc, initStyle, styler); if (sc.currentLine > 0) { int lineState = styler.GetLineState(sc.currentLine - 1); /* @@ -329,12 +329,16 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i UnpackLineState(lineState, nestedState); } } - if (startPos == 0 && sc.Match('#', '!')) { + if (startPos == 0) { + if (sc.Match('#', '!')) { // Shell Shebang at beginning of file sc.SetState(SCE_DART_COMMENTLINE); sc.Forward(); lineStateLineType = DartLineStateMaskLineComment; } + } else if (IsSpaceEquiv(initStyle)) { + LookbackNonWhite(styler, startPos, SCE_DART_TASKMARKER, chPrevNonWhite, initStyle); + } while (sc.More()) { switch (sc.state) { @@ -350,75 +354,15 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i break; case SCE_DART_IDENTIFIER: + case SCE_DART_VARIABLE: + case SCE_DART_VARIABLE2: + case SCE_DART_METADATA: + case SCE_DART_SYMBOL_IDENTIFIER: if (!IsIdentifierCharEx(sc.ch)) { - char s[128]; - sc.GetCurrent(s, sizeof(s)); - if (wl_keywords.InList(s)) { - sc.ChangeState(SCE_DART_WORD); - if (StrEqualsAny(s, "import", "part")) { - if (visibleChars == sc.LengthCurrent()) { - lineStateLineType = DartLineStateMaskImport; - } - } - else if (StrEqualsAny(s, "class", "extends", "implements", "new", "throw", "as", "is")) { - kwType = SCE_DART_CLASS; - } - else if (StrEqual(s, "enum")) { - kwType = SCE_DART_ENUM; - } - else if (StrEqualsAny(s, "break", "continue")) { - kwType = SCE_DART_LABEL; - } - if (kwType != SCE_DART_DEFAULT) { - const int chNext = GetLineNextChar(styler, sc); - if (!IsIdentifierStartEx(chNext)) { - kwType = SCE_DART_DEFAULT; - } - } - } - else if (wl_keywords2.InList(s)) { - sc.ChangeState(SCE_DART_WORD2); - } - else if (wl_classes.InList(s)) { - sc.ChangeState(SCE_DART_CLASS); - } - else if (wl_enums.InList(s)) { - sc.ChangeState(SCE_DART_ENUM); - } - else if (sc.ch == ':') { - if (visibleChars == sc.LengthCurrent()) { - const int chNext = GetLineNextChar(styler, sc, true); - if (IsJumpLabelNextChar(chNext)) { - sc.ChangeState(SCE_DART_LABEL); - } - } - } - else if (sc.ch != '.') { - if (kwType != SCE_DART_DEFAULT) { - sc.ChangeState(kwType); - } - else { - const int chNext = GetDocNextChar(styler, sc, (sc.ch == '?')); - if (chNext == '(') { - sc.ChangeState(SCE_DART_FUNCTION); - } - else if ((chBeforeIdentifier == '<' && (chNext == '>' || chNext == '<')) - || IsIdentifierStartEx(chNext)) { - // type - // type - // type> - // type identifier - // type? identifier - sc.ChangeState(SCE_DART_CLASS); - } - } - } - if (sc.state != SCE_DART_WORD && sc.ch != '.') { - kwType = SCE_DART_DEFAULT; - } - sc.SetState(SCE_DART_DEFAULT); - } - break; + switch (sc.state) { + case SCE_DART_VARIABLE2: + sc.SetState(escSeq.outerState); + continue; case SCE_DART_METADATA: case SCE_DART_SYMBOL_IDENTIFIER: @@ -428,7 +372,77 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i sc.ForwardSetState(state); continue; } - if (!IsIdentifierCharEx(sc.ch)) { + break; + + case SCE_DART_IDENTIFIER: { + char s[128]; + sc.GetCurrent(s, sizeof(s)); + if (keywordLists[KeywordIndex_Keyword].InList(s)) { + sc.ChangeState(SCE_DART_WORD); + if (StrEqualsAny(s, "import", "part")) { + if (visibleChars == sc.LengthCurrent()) { + lineStateLineType = DartLineStateMaskImport; + } + } else if (StrEqualsAny(s, "class", "extends", "implements", "new", "throw", "with", "as", "is", "on")) { + kwType = KeywordType::Class; + } else if (StrEqual(s, "enum")) { + kwType = KeywordType::Enum; + } else if (StrEqualsAny(s, "break", "continue")) { + kwType = KeywordType::Label; + } else if (StrEqualsAny(s, "return", "await", "yield")) { + kwType = KeywordType::Return; + } + if (kwType > KeywordType::None && kwType < KeywordType::Return) { + const int chNext = sc.GetLineNextChar(); + if (!IsIdentifierStartEx(chNext)) { + kwType = KeywordType::None; + } + } + } else if (keywordLists[KeywordIndex_Type].InList(s)) { + sc.ChangeState(SCE_DART_WORD2); + } else if (keywordLists[KeywordIndex_Class].InList(s)) { + sc.ChangeState(SCE_DART_CLASS); + } else if (keywordLists[KeywordIndex_Enumeration].InList(s)) { + sc.ChangeState(SCE_DART_ENUM); + } else if (sc.ch == ':') { + if (chBefore == ',' || chBefore == '{') { + sc.ChangeState(SCE_DART_KEY); + } else if (IsJumpLabelPrevChar(chBefore)) { + sc.ChangeState(SCE_DART_LABEL); + } + } else if (sc.ch != '.') { + if (kwType > KeywordType::None && kwType < KeywordType::Return) { + sc.ChangeState(static_cast(kwType)); + } else { + const int chNext = sc.GetDocNextChar(sc.ch == '?'); + if (chNext == '(') { + // type method() + // type[] method() + // type method() + if (kwType != KeywordType::Return && (IsIdentifierCharEx(chBefore) || chBefore == ']')) { + sc.ChangeState(SCE_DART_FUNCTION_DEFINITION); + } else { + sc.ChangeState(SCE_DART_FUNCTION); + } + } else if ((chBeforeIdentifier == '<' && (chNext == '>' || chNext == '<')) + || IsIdentifierStartEx(chNext)) { + // type + // type + // type> + // type + // class type implements interface, interface {} + // type identifier + // type? identifier + sc.ChangeState(SCE_DART_CLASS); + } + } + } + if (sc.state != SCE_DART_WORD && sc.ch != '.') { + kwType = KeywordType::None; + } + } break; + } + sc.SetState(SCE_DART_DEFAULT); } break; @@ -443,8 +457,7 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i case SCE_DART_COMMENTLINEDOC: if (sc.atLineStart) { sc.SetState(SCE_DART_DEFAULT); - } - else { + } else { HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_DART_TASKMARKER); } break; @@ -457,79 +470,69 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i if (commentLevel == 0) { sc.ForwardSetState(SCE_DART_DEFAULT); } - } - else if (sc.Match('/', '*')) { + } else if (sc.Match('/', '*')) { sc.Forward(); ++commentLevel; - } - else if (HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_DART_TASKMARKER)) { + } else if (HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_DART_TASKMARKER)) { continue; } break; - case SCE_DART_RAWSTRING_SQ: - case SCE_DART_RAWSTRING_DQ: - if (sc.atLineStart) { - sc.SetState(SCE_DART_DEFAULT); - } - else if ((sc.state == SCE_DART_RAWSTRING_SQ && sc.ch == '\'') - || (sc.state == SCE_DART_RAWSTRING_DQ && sc.ch == '"')) { - sc.ForwardSetState(SCE_DART_DEFAULT); - } - break; - - case SCE_DART_TRIPLE_RAWSTRING_SQ: - case SCE_DART_TRIPLE_RAWSTRING_DQ: - if ((sc.state == SCE_DART_TRIPLE_RAWSTRING_SQ && sc.Match('\'', '\'', '\'')) - || (sc.state == SCE_DART_TRIPLE_RAWSTRING_DQ && sc.Match('"', '"', '"'))) { - sc.Forward(2); - sc.ForwardSetState(SCE_DART_DEFAULT); - } - break; - case SCE_DART_STRING_SQ: case SCE_DART_STRING_DQ: case SCE_DART_TRIPLE_STRING_SQ: case SCE_DART_TRIPLE_STRING_DQ: - if ((sc.state == SCE_DART_STRING_SQ || sc.state == SCE_DART_STRING_DQ) && sc.atLineStart) { + case SCE_DART_RAWSTRING_SQ: + case SCE_DART_RAWSTRING_DQ: + case SCE_DART_TRIPLE_RAWSTRING_SQ: + case SCE_DART_TRIPLE_RAWSTRING_DQ: + if (sc.atLineStart && !IsTripleString(sc.state)) { sc.SetState(SCE_DART_DEFAULT); - } - else if (sc.ch == '\\') { + } else if (sc.ch == '\\' && sc.state < SCE_DART_RAWSTRING_SQ) { if (escSeq.resetEscapeState(sc.state, sc.chNext)) { sc.SetState(SCE_DART_ESCAPECHAR); sc.Forward(); + if (sc.Match('u', '{')) { + escSeq.brace = true; + escSeq.digitsLeft = 7; // Unicode code point + sc.Forward(); } } - else if (sc.ch == '$') { - if (sc.chNext == '{') { + } else if (sc.ch == '$' && sc.state < SCE_DART_RAWSTRING_SQ) { + if (sc.chNext == '{' || sc.chNext == '(') { + if (sc.chNext == '(') { + simpleStringInterpolation = true; + escSeq.outerState = sc.state; + } else { nestedState.push_back(sc.state); + } sc.SetState(SCE_DART_OPERATOR2); sc.Forward(); - } - else if (IsIdentifierStartEx(sc.chNext)) { + } else if (IsIdentifierStartEx(sc.chNext)) { escSeq.outerState = sc.state; - sc.SetState(SCE_DART_VARIABLE); + sc.SetState(SCE_DART_VARIABLE2); } - } - else if ((sc.ch == '\'' && (sc.state == SCE_DART_STRING_SQ || (sc.state == SCE_DART_TRIPLE_STRING_SQ && sc.MatchNext('\'', '\'')))) - || (sc.ch == '"' && (sc.state == SCE_DART_STRING_DQ || (sc.state == SCE_DART_TRIPLE_STRING_DQ && sc.MatchNext('"', '"'))))) { - if (sc.state == SCE_DART_TRIPLE_STRING_SQ || sc.state == SCE_DART_TRIPLE_STRING_DQ) { - sc.SetState(SCE_DART_TRIPLE_STRINGEND); + } else if (sc.ch == GetStringQuote(sc.state) && (!IsTripleString(sc.state) || sc.MatchNext())) { + if (IsTripleString(sc.state)) { + //sc.Advance(2); sc.Forward(2); } - sc.ForwardSetState(SCE_DART_DEFAULT); + sc.Forward(); + if (sc.state <= SCE_DART_STRING_DQ && (chBefore == ',' || chBefore == '{')) { + const int chNext = sc.GetLineNextChar(); + if (chNext == ':') { + sc.ChangeState(SCE_DART_KEY); + } + } + sc.SetState(SCE_DART_DEFAULT); } break; case SCE_DART_ESCAPECHAR: if (escSeq.atEscapeEnd(sc.ch)) { - sc.SetState(escSeq.outerState); - continue; + if (escSeq.brace && sc.ch == '}') { + sc.Forward(); } - break; - - case SCE_DART_VARIABLE: - if (!IsIdentifierCharEx(sc.ch)) { sc.SetState(escSeq.outerState); continue; } @@ -549,8 +552,7 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i if (visibleChars == 0) { lineStateLineType = DartLineStateMaskLineComment; } - } - else { + } else { commentLevel = 1; } continue; @@ -561,8 +563,7 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i if (sc.chPrev == '\'' && sc.Match('\'', '\'')) { sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_SQ); sc.Forward(2); - } - else if (sc.chPrev == '"' && sc.Match('"', '"')) { + } else if (sc.chPrev == '"' && sc.Match('"', '"')) { sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_DQ); sc.Forward(2); } @@ -570,51 +571,51 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i } if (sc.ch == '"') { if (sc.MatchNext('"', '"')) { - sc.SetState(SCE_DART_TRIPLE_STRINGSTART); + sc.SetState(SCE_DART_TRIPLE_STRING_DQ); + //sc.Advance(2); sc.Forward(2); - sc.ForwardSetState(SCE_DART_TRIPLE_STRING_DQ); - continue; - } + } else { + chBefore = chPrevNonWhite; sc.SetState(SCE_DART_STRING_DQ); } - else if (sc.ch == '\'') { + } else if (sc.ch == '\'') { if (sc.MatchNext('\'', '\'')) { - sc.SetState(SCE_DART_TRIPLE_STRINGSTART); + sc.SetState(SCE_DART_TRIPLE_STRING_SQ); + //sc.Advance(2); sc.Forward(2); - sc.ForwardSetState(SCE_DART_TRIPLE_STRING_SQ); - continue; - } + } else { + chBefore = chPrevNonWhite; sc.SetState(SCE_DART_STRING_SQ); } - else if (IsNumberStart(sc.ch, sc.chNext)) { + } else if (IsNumberStart(sc.ch, sc.chNext)) { sc.SetState(SCE_DART_NUMBER); - } - else if ((sc.ch == '@' || sc.ch == '$') && IsIdentifierStartEx(sc.chNext)) { - escSeq.outerState = SCE_DART_DEFAULT; + } else if ((sc.ch == '@' || sc.ch == '$') && IsIdentifierStartEx(sc.chNext)) { sc.SetState((sc.ch == '@') ? SCE_DART_METADATA : SCE_DART_VARIABLE); - } - else if (sc.ch == '#') { + } else if (sc.ch == '#') { if (IsIdentifierStartEx(sc.chNext)) { sc.SetState(SCE_DART_SYMBOL_IDENTIFIER); - } - else if (IsDeclarableOperator(sc.chNext)) { + } else if (IsDeclarableOperator(sc.chNext)) { sc.SetState(SCE_DART_SYMBOL_OPERATOR); } - } - else if (IsIdentifierStartEx(sc.ch)) { - if (sc.chPrev != '.') { - chBeforeIdentifier = sc.chPrev; + } else if (IsIdentifierStartEx(sc.ch)) { + chBefore = chPrevNonWhite; + if (chPrevNonWhite != '.') { + chBeforeIdentifier = chPrevNonWhite; } sc.SetState(SCE_DART_IDENTIFIER); + } else if (IsAGraphic(sc.ch)) { + sc.SetState(SCE_DART_OPERATOR); + if (simpleStringInterpolation && sc.ch == ')') { + simpleStringInterpolation = false; + sc.ChangeState(SCE_DART_OPERATOR2); + sc.ForwardSetState(escSeq.outerState); + continue; } - else if (isoperator(sc.ch)) { - const bool interpolating = !nestedState.empty(); - sc.SetState(interpolating ? SCE_DART_OPERATOR2 : SCE_DART_OPERATOR); - if (interpolating) { + if (!nestedState.empty()) { + sc.ChangeState(SCE_DART_OPERATOR2); if (sc.ch == '{') { nestedState.push_back(SCE_DART_DEFAULT); - } - else if (sc.ch == '}') { + } else if (sc.ch == '}') { const int outerState = TakeAndPop(nestedState); sc.ForwardSetState(outerState); continue; @@ -625,6 +626,9 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i if (!isspacechar(sc.ch)) { visibleChars++; + if (!IsSpaceEquiv(sc.state)) { + chPrevNonWhite = sc.ch; + } } if (sc.atLineEnd) { int lineState = (commentLevel << 2) | lineStateLineType; @@ -635,34 +639,23 @@ void SCI_METHOD LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, i lineStateLineType = 0; visibleChars = 0; visibleCharsBefore = 0; - kwType = SCE_DART_DEFAULT; + kwType = KeywordType::None; } sc.Forward(); } sc.Complete(); } -// ---------------------------------------------------------------------------- - - - - -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- struct FoldLineState { int lineComment; int packageImport; constexpr explicit FoldLineState(int lineState) noexcept : - lineComment(lineState& DartLineStateMaskLineComment), + lineComment(lineState & DartLineStateMaskLineComment), packageImport((lineState >> 1) & 1) { } }; -constexpr bool IsStreamCommentStyle(int style) noexcept { - return style == SCE_DART_COMMENTBLOCK || style == SCE_DART_COMMENTBLOCKDOC; -} - void SCI_METHOD LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int, IDocument* pAccess) { if (!options.fold) { return; } @@ -690,19 +683,19 @@ void SCI_METHOD LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int levelNext = levelCurrent; FoldLineState foldCurrent(styler.GetLineState(lineCurrent)); Sci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1); - Sci_PositionU lineEndPos = sci::min(lineStartNext, endPos) - 1; + lineStartNext = sci::min(lineStartNext, endPos); char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = styleNext; int visibleChars = 0; - for (Sci_PositionU i = startPos; i < endPos; i++) { + while (startPos < endPos) { const char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); const int stylePrev = style; style = styleNext; - styleNext = styler.StyleAt(i + 1); + chNext = styler[++startPos]; + styleNext = styler.StyleAt(startPos); switch (style) { case SCE_DART_COMMENTBLOCKDOC: @@ -710,39 +703,29 @@ void SCI_METHOD LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, const int level = (ch == '/' && chNext == '*') ? 1 : ((ch == '*' && chNext == '/') ? -1 : 0); if (level != 0) { levelNext += level; - i++; - chNext = styler.SafeGetCharAt(i + 1); - styleNext = styler.StyleAt(i + 1); + startPos++; + chNext = styler[startPos]; + styleNext = styler.StyleAt(startPos); } } break; case SCE_DART_TRIPLE_RAWSTRING_SQ: case SCE_DART_TRIPLE_RAWSTRING_DQ: + case SCE_DART_TRIPLE_STRING_SQ: + case SCE_DART_TRIPLE_STRING_DQ: if (style != stylePrev) { levelNext++; } - else if (style != styleNext) { - levelNext--; - } - break; - - case SCE_DART_TRIPLE_STRINGSTART: - if (style != stylePrev) { - levelNext++; - } - break; - - case SCE_DART_TRIPLE_STRINGEND: if (style != styleNext) { levelNext--; } break; case SCE_DART_OPERATOR: + case SCE_DART_OPERATOR2: if (ch == '{' || ch == '[' || ch == '(') { levelNext++; - } - else if (ch == '}' || ch == ']' || ch == ')') { + } else if (ch == '}' || ch == ']' || ch == ')') { levelNext--; } break; @@ -751,20 +734,21 @@ void SCI_METHOD LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, if (visibleChars == 0 && !IsSpaceEquiv(style)) { ++visibleChars; } - if (i == lineEndPos) { + if (startPos == lineStartNext) { const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1)); + levelNext = sci::max(levelNext, SC_FOLDLEVELBASE); if (foldCurrent.lineComment) { levelNext += foldNext.lineComment - foldPrev.lineComment; - } - else if (foldCurrent.packageImport) { + } else if (foldCurrent.packageImport) { levelNext += foldNext.packageImport - foldPrev.packageImport; - } - else if (visibleChars) { + } else if (visibleChars) { const Sci_PositionU bracePos = CheckBraceOnNextLine(styler, lineCurrent, SCE_DART_OPERATOR, SCE_DART_TASKMARKER); if (bracePos) { levelNext++; - i = bracePos; // skip the brace - chNext = '\0'; + startPos = bracePos + 1; // skip the brace + style = SCE_DART_OPERATOR; + chNext = styler[startPos]; + styleNext = styler.StyleAt(startPos); } } @@ -773,13 +757,11 @@ void SCI_METHOD LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, if (levelUse < levelNext) { lev |= SC_FOLDLEVELHEADERFLAG; } - if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); - } lineCurrent++; lineStartNext = styler.LineStart(lineCurrent + 1); - lineEndPos = sci::min(lineStartNext, endPos) - 1; + lineStartNext = sci::min(lineStartNext, endPos); levelCurrent = levelNext; foldPrev = foldCurrent; foldCurrent = foldNext; diff --git a/lexilla/lexers_x/LexKotlin.cxx b/lexilla/lexers_x/LexKotlin.cxx index 7bc7e49c1..7b5f3125d 100644 --- a/lexilla/lexers_x/LexKotlin.cxx +++ b/lexilla/lexers_x/LexKotlin.cxx @@ -53,7 +53,9 @@ struct OptionsKotlin static const char* const kotlinWordLists[] = { "Keywords", + "Java Classes" "Classes", + "Java Interfaces" "Interfaces", "Enums", "Annotations", @@ -62,6 +64,7 @@ static const char* const kotlinWordLists[] = nullptr }; + struct OptionSetKotlin : public OptionSet { OptionSetKotlin() @@ -77,32 +80,31 @@ struct OptionSetKotlin : public OptionSet LexicalClass lexicalClasses[] = { // Lexer Dart SCLEX_DART SCE_DART_: - SCE_KOTLIN_DEFAULT, "SCE_KOTLIN_DEFAULT", "default", "Descr", - SCE_KOTLIN_COMMENTLINE, "SCE_KOTLIN_COMMENTLINE", "commentline", "Descr", - SCE_KOTLIN_COMMENTLINEDOC, "SCE_KOTLIN_COMMENTLINEDOC", "commentlinedoc", "Descr", - SCE_KOTLIN_COMMENTBLOCK, "SCE_KOTLIN_COMMENTBLOCK", "commentblock", "Descr", - SCE_KOTLIN_COMMENTBLOCKDOC, "SCE_KOTLIN_COMMENTBLOCKDOC", "commentblockdoc", "Descr", - SCE_KOTLIN_COMMENTDOCWORD, "SCE_KOTLIN_COMMENTDOCWORD", "commentdocword", "Descr", - SCE_KOTLIN_TASKMARKER, "SCE_KOTLIN_TASKMARKER", "taskmarker", "Descr", - SCE_KOTLIN_NUMBER, "SCE_KOTLIN_NUMBER", "number", "Descr", - SCE_KOTLIN_OPERATOR, "SCE_KOTLIN_OPERATOR", "operator", "Descr", - SCE_KOTLIN_OPERATOR2, "SCE_KOTLIN_OPERATOR2", "operator2", "Descr", - SCE_KOTLIN_CHARACTER, "SCE_KOTLIN_CHARACTER", "character", "Descr", - SCE_KOTLIN_STRING, "SCE_KOTLIN_STRING", "string", "Descr", - SCE_KOTLIN_RAWSTRING, "SCE_KOTLIN_RAWSTRING ", "rawstring", "Descr", - SCE_KOTLIN_ESCAPECHAR, "SCE_KOTLIN_ESCAPECHAR", "escapechar", "Descr", - SCE_KOTLIN_RAWSTRINGSTART, "SCE_KOTLIN_RAWSTRINGSTART", "rawstring_start", "Descr", - SCE_KOTLIN_RAWSTRINGEND, "SCE_KOTLIN_RAWSTRINGEND", "rawstring_end", "Descr", - SCE_KOTLIN_BACKTICKS, "SCE_KOTLIN_BACKTICKS", "backticks", "Descr", - SCE_KOTLIN_VARIABLE, "SCE_KOTLIN_VARIABLE", "variable", "Descr", - SCE_KOTLIN_ANNOTATION, "SCE_KOTLIN_ANNOTATION", "annotation", "Descr", - SCE_KOTLIN_LABEL, "SCE_KOTLIN_LABEL", "label", "Descr", - SCE_KOTLIN_IDENTIFIER, "SCE_KOTLIN_IDENTIFIER", "identifier", "Descr", - SCE_KOTLIN_WORD, "SCE_KOTLIN_WORD", "word", "Descr", - SCE_KOTLIN_CLASS, "SCE_KOTLIN_CLASS", "class", "Descr", - SCE_KOTLIN_INTERFACE, "SCE_KOTLIN_INTERFACE", "interface", "Descr", - SCE_KOTLIN_ENUM, "SCE_KOTLIN_ENUM", "enum", "Descr", - SCE_KOTLIN_FUNCTION, "SCE_KOTLIN_FUNCTION", "function", "Descr", + SCE_KOTLIN_DEFAULT, "SCE_KOTLIN_DEFAULT", "default", "Descr", + SCE_KOTLIN_COMMENTLINE, "SCE_KOTLIN_COMMENTLINE", "commentline", "Descr", + SCE_KOTLIN_COMMENTLINEDOC, "SCE_KOTLIN_COMMENTLINEDOC", "commentlinedoc", "Descr", + SCE_KOTLIN_COMMENTBLOCK, "SCE_KOTLIN_COMMENTBLOCK", "commentblock", "Descr", + SCE_KOTLIN_COMMENTBLOCKDOC, "SCE_KOTLIN_COMMENTBLOCKDOC", "commentblockdoc", "Descr", + SCE_KOTLIN_COMMENTDOCWORD, "SCE_KOTLIN_COMMENTDOCWORD", "commentdocword", "Descr", + SCE_KOTLIN_TASKMARKER, "SCE_KOTLIN_TASKMARKER", "taskmarker", "Descr", + SCE_KOTLIN_NUMBER, "SCE_KOTLIN_NUMBER", "number", "Descr", + SCE_KOTLIN_OPERATOR, "SCE_KOTLIN_OPERATOR", "operator", "Descr", + SCE_KOTLIN_OPERATOR2, "SCE_KOTLIN_OPERATOR2", "operator2", "Descr", + SCE_KOTLIN_CHARACTER, "SCE_KOTLIN_CHARACTER", "character", "Descr", + SCE_KOTLIN_STRING, "SCE_KOTLIN_STRING", "string", "Descr", + SCE_KOTLIN_RAWSTRING, "SCE_KOTLIN_RAWSTRING ", "rawstring", "Descr", + SCE_KOTLIN_ESCAPECHAR, "SCE_KOTLIN_ESCAPECHAR", "escapechar", "Descr", + SCE_KOTLIN_VARIABLE, "SCE_KOTLIN_VARIABLE", "variable", "Descr", + SCE_KOTLIN_LABEL, "SCE_KOTLIN_LABEL", "label", "Descr", + SCE_KOTLIN_IDENTIFIER, "SCE_KOTLIN_IDENTIFIER", "identifier", "Descr", + SCE_KOTLIN_ANNOTATION, "SCE_KOTLIN_ANNOTATION", "annotation", "Descr", + SCE_KOTLIN_BACKTICKS, "SCE_KOTLIN_BACKTICKS", "backticks", "Descr", + SCE_KOTLIN_WORD, "SCE_KOTLIN_WORD", "word", "Descr", + SCE_KOTLIN_CLASS, "SCE_KOTLIN_CLASS", "class", "Descr", + SCE_KOTLIN_INTERFACE, "SCE_KOTLIN_INTERFACE", "interface", "Descr", + SCE_KOTLIN_ENUM, "SCE_KOTLIN_ENUM", "enum", "Descr", + SCE_KOTLIN_FUNCTION, "SCE_KOTLIN_FUNCTION", "function", "Descr", + SCE_KOTLIN_FUNCTION_DEFINITION, "SCE_KOTLIN_FUNCTION_DEFINITION", "functiondef", "Descr", }; } // end of namespace @@ -115,13 +117,7 @@ class LexerKotlin : public DefaultLexer //CharacterSet validNumberEnd; //CharacterSet chDateTime; - WordList wl_keywords; - WordList wl_classes; - WordList wl_interfaces; - WordList wl_enums; - WordList wl_annotations; - WordList wl_functions; - WordList wl_kdocs; + WordList keywordLists[KEYWORDSET_MAX+1]; OptionsKotlin options; OptionSetKotlin osKotlin; @@ -135,7 +131,7 @@ public: //, chDateTime(CharacterSet::setNone, "-+.:TZ", 0x80, false) { } - virtual ~LexerKotlin() { } + virtual ~LexerKotlin() = default; void SCI_METHOD Release() override { @@ -211,35 +207,21 @@ Sci_Position SCI_METHOD LexerKotlin::PropertySet(const char* key, const char* va return -1; } +enum { + KeywordIndex_Keyword = 0, + KeywordIndex_JavaClass = 1, + KeywordIndex_Class = 2, + KeywordIndex_JavaInterface = 3, + KeywordIndex_Interface = 4, + KeywordIndex_Enumeration = 5, + KeywordIndex_Annotation = 6, + KeywordIndex_Function = 7, + KeywordIndex_KDoc = 8 +}; Sci_Position SCI_METHOD LexerKotlin::WordListSet(int n, const char* wl) { - WordList* wordListN = nullptr; - - switch (n) - { - case 0: - wordListN = &wl_keywords; - break; - case 1: - wordListN = &wl_classes; - break; - case 2: - wordListN = &wl_interfaces; - break; - case 3: - wordListN = &wl_enums; - break; - case 4: - wordListN = &wl_annotations; - break; - case 5: - wordListN = &wl_functions; - break; - case 6: - wordListN = &wl_kdocs; - break; - } + WordList* wordListN = &(keywordLists[n]); Sci_Position firstModification = -1LL; if (wordListN) { @@ -251,15 +233,8 @@ Sci_Position SCI_METHOD LexerKotlin::WordListSet(int n, const char* wl) } // ---------------------------------------------------------------------------- -enum { - KotlinLineStateMaskLineComment = 1, // line comment - KotlinLineStateMaskImport = 1 << 1, // import -}; - -static_assert(DefaultNestedStateBaseStyle + 1 == SCE_KOTLIN_STRING); -static_assert(DefaultNestedStateBaseStyle + 2 == SCE_KOTLIN_RAWSTRING); - struct EscapeSequence { + int outerState = SCE_KOTLIN_DEFAULT; int digitsLeft = 0; @@ -274,10 +249,27 @@ struct EscapeSequence { } bool atEscapeEnd(int ch) noexcept { --digitsLeft; - return digitsLeft <= 0 || !IsAHexDigit(ch); + return digitsLeft <= 0 || !IsHexDigit(ch); } }; +enum { + KotlinLineStateMaskLineComment = 1, // line comment + KotlinLineStateMaskImport = 1 << 1, // import +}; + +enum class KeywordType { + None = SCE_KOTLIN_DEFAULT, + Annotation = SCE_KOTLIN_ANNOTATION, + Class = SCE_KOTLIN_CLASS, + Interface = SCE_KOTLIN_INTERFACE, + Enum = SCE_KOTLIN_ENUM, + Label = SCE_KOTLIN_LABEL, + Return = 0x40, +}; + +static_assert(DefaultNestedStateBaseStyle + 1 == SCE_KOTLIN_STRING); +static_assert(DefaultNestedStateBaseStyle + 2 == SCE_KOTLIN_RAWSTRING); constexpr bool IsSpaceEquiv(int state) noexcept { return state <= SCE_KOTLIN_TASKMARKER; @@ -293,20 +285,22 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, { PropSetSimple props; Accessor styler(pAccess, &props); - StyleContext sc(startPos, lengthDoc, initStyle, styler); int lineStateLineType = 0; int commentLevel = 0; // nested block comment level - int kwType = SCE_KOTLIN_DEFAULT; + KeywordType kwType = KeywordType::None; int chBeforeIdentifier = 0; std::vector nestedState; // string interpolation "${}" int visibleChars = 0; + int chBefore = 0; int visibleCharsBefore = 0; + int chPrevNonWhite = 0; EscapeSequence escSeq; + StyleContext sc(startPos, lengthDoc, initStyle, styler); if (sc.currentLine > 0) { int lineState = styler.GetLineState(sc.currentLine - 1); /* @@ -320,8 +314,7 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, if (lineState) { UnpackLineState(lineState, nestedState); } - } - if (startPos == 0 && sc.Match('#', '!')) { + } else if (startPos == 0 && sc.Match('#', '!')) { // Shell Shebang at beginning of file sc.SetState(SCE_KOTLIN_COMMENTLINE); sc.Forward(); @@ -341,85 +334,15 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, } break; - case SCE_KOTLIN_IDENTIFIER: - if (!IsIdentifierCharEx(sc.ch)) { - char s[128]; - sc.GetCurrent(s, sizeof(s)); - if (wl_keywords.InList(s)) { - sc.ChangeState(SCE_KOTLIN_WORD); - if (StrEqual(s, "import")) { - if (visibleChars == sc.LengthCurrent()) { - lineStateLineType = KotlinLineStateMaskImport; - } - } - else if (StrEqualsAny(s, "break", "continue", "return", "this", "super")) { - kwType = SCE_KOTLIN_LABEL; - } - else if (StrEqualsAny(s, "class", "typealias")) { - if (!(kwType == SCE_KOTLIN_ANNOTATION || kwType == SCE_KOTLIN_ENUM)) { - kwType = SCE_KOTLIN_CLASS; - } - } - else if (StrEqual(s, "enum")) { - kwType = SCE_KOTLIN_ENUM; - } - else if (StrEqual(s, "annotation")) { - kwType = SCE_KOTLIN_ANNOTATION; - } - else if (StrEqual(s, "interface")) { - kwType = SCE_KOTLIN_INTERFACE; - } - if (kwType != SCE_KOTLIN_DEFAULT) { - /*const int chNext =*/ GetDocNextChar(styler, sc); - if (!((kwType == SCE_KOTLIN_LABEL && sc.ch == '@') || (kwType != SCE_KOTLIN_LABEL && IsIdentifierStartEx(sc.ch)))) { - kwType = SCE_KOTLIN_DEFAULT; - } - } - } - else if (sc.ch == '@') { - sc.ChangeState(SCE_KOTLIN_LABEL); - sc.Forward(); - } - else if (wl_classes.InList(s)) { - sc.ChangeState(SCE_KOTLIN_CLASS); - } - else if (wl_interfaces.InList(s)) { - sc.ChangeState(SCE_KOTLIN_INTERFACE); - } - else if (wl_enums.InList(s)) { - sc.ChangeState(SCE_KOTLIN_ENUM); - } - else if (sc.ch != '.') { - if (kwType != SCE_KOTLIN_DEFAULT && kwType != SCE_KOTLIN_LABEL) { - sc.ChangeState(kwType); - } - else { - /*const int chNext =*/ GetDocNextChar(styler, sc, (sc.ch == '?')); - if (sc.ch == '(') { - sc.ChangeState(SCE_KOTLIN_FUNCTION); - } - else if (sc.Match(':', ':') - || (chBeforeIdentifier == '<' && (sc.ch == '>' || sc.ch == '<'))) { - // type::class - // type - // type - // type> - sc.ChangeState(SCE_KOTLIN_CLASS); - } - } - } - if (sc.state != SCE_KOTLIN_WORD && sc.ch != '.') { - kwType = SCE_KOTLIN_DEFAULT; - } - sc.SetState(SCE_KOTLIN_DEFAULT); - } - break; - + case SCE_KOTLIN_VARIABLE: case SCE_KOTLIN_LABEL: + case SCE_KOTLIN_IDENTIFIER: + case SCE_KOTLIN_ANNOTATION: if (!IsIdentifierCharEx(sc.ch)) { - sc.SetState(SCE_KOTLIN_DEFAULT); - } - break; + switch (sc.state) { + case SCE_KOTLIN_VARIABLE: + sc.SetState(escSeq.outerState); + continue; case SCE_KOTLIN_ANNOTATION: if (sc.ch == '.' || sc.ch == ':') { @@ -427,7 +350,78 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, sc.ForwardSetState(SCE_KOTLIN_ANNOTATION); continue; } - if (!IsIdentifierCharEx(sc.ch)) { + break; + + case SCE_KOTLIN_IDENTIFIER: { + char s[128]; + sc.GetCurrent(s, sizeof(s)); + if (keywordLists[KeywordIndex_Keyword].InList(s)) { + sc.ChangeState(SCE_KOTLIN_WORD); + if (StrEqual(s, "import")) { + if (visibleChars == sc.LengthCurrent()) { + lineStateLineType = KotlinLineStateMaskImport; + } + } else if (StrEqualsAny(s, "break", "continue", "return", "this", "super")) { + kwType = KeywordType::Label; + } else if (StrEqualsAny(s, "class", "typealias")) { + if (!(kwType == KeywordType::Annotation || kwType == KeywordType::Enum)) { + kwType = KeywordType::Class; + } + } else if (StrEqual(s, "enum")) { + kwType = KeywordType::Enum; + } else if (StrEqual(s, "annotation")) { + kwType = KeywordType::Annotation; + } else if (StrEqual(s, "interface")) { + kwType = KeywordType::Interface; + } else if (StrEqual(s, "return")) { + kwType = KeywordType::Return; + } + if (kwType > KeywordType::None && kwType < KeywordType::Return) { + const int chNext = sc.GetDocNextChar(); + if (!((kwType == KeywordType::Label) ? (chNext == '@') : IsIdentifierStartEx(chNext))) { + kwType = KeywordType::None; + } + } + } else if (sc.ch == '@') { + sc.ChangeState(SCE_KOTLIN_LABEL); + sc.Forward(); + } else if (keywordLists[KeywordIndex_JavaClass].InList(s) || keywordLists[KeywordIndex_Class].InList(s)) { + sc.ChangeState(SCE_KOTLIN_CLASS); + } else if (keywordLists[KeywordIndex_JavaInterface].InList(s) || keywordLists[KeywordIndex_Interface].InList(s)) { + sc.ChangeState(SCE_KOTLIN_INTERFACE); + } else if (keywordLists[KeywordIndex_Enumeration].InList(s)) { + sc.ChangeState(SCE_KOTLIN_ENUM); + } else if (sc.ch != '.') { + if (kwType > KeywordType::None && kwType < KeywordType::Return) { + sc.ChangeState(static_cast(kwType)); + } else { + const int chNext = sc.GetDocNextChar(sc.ch == '?'); + if (chNext == '(') { + // type function() + // type[] function() + // type function() + if (kwType != KeywordType::Return && (IsIdentifierCharEx(chBefore) || chBefore == ']')) { + sc.ChangeState(SCE_KOTLIN_FUNCTION_DEFINITION); + } else { + sc.ChangeState(SCE_KOTLIN_FUNCTION); + } + } else if (sc.Match(':', ':') + || (chBeforeIdentifier == '<' && (chNext == '>' || chNext == '<'))) { + // type::class + // type + // type + // type> + // type + // class type: type, interface {} + sc.ChangeState(SCE_KOTLIN_CLASS); + } + } + } + if (sc.state != SCE_KOTLIN_WORD && sc.ch != '.') { + kwType = KeywordType::None; + } + } break; + } sc.SetState(SCE_KOTLIN_DEFAULT); } break; @@ -436,8 +430,7 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, case SCE_KOTLIN_COMMENTLINEDOC: if (sc.atLineStart) { sc.SetState(SCE_KOTLIN_DEFAULT); - } - else { + } else { HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_KOTLIN_TASKMARKER); } break; @@ -446,19 +439,16 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, case SCE_KOTLIN_COMMENTBLOCKDOC: if (sc.state == SCE_KOTLIN_COMMENTBLOCKDOC && sc.ch == '@' && IsLowerCase(sc.chNext) && IsCommentTagPrev(sc.chPrev)) { sc.SetState(SCE_KOTLIN_COMMENTDOCWORD); - } - else if (sc.Match('*', '/')) { + } else if (sc.Match('*', '/')) { sc.Forward(); --commentLevel; if (commentLevel == 0) { sc.ForwardSetState(SCE_KOTLIN_DEFAULT); } - } - else if (sc.Match('/', '*')) { + } else if (sc.Match('/', '*')) { sc.Forward(); ++commentLevel; - } - else if (HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_KOTLIN_TASKMARKER)) { + } else if (HighlightTaskMarker(sc, visibleChars, visibleCharsBefore, SCE_KOTLIN_TASKMARKER)) { continue; } break; @@ -470,49 +460,35 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, } break; + case SCE_KOTLIN_CHARACTER: case SCE_KOTLIN_STRING: case SCE_KOTLIN_RAWSTRING: - if (sc.state == SCE_KOTLIN_STRING && sc.atLineStart) { + if (sc.atLineStart && sc.state != SCE_KOTLIN_RAWSTRING) { sc.SetState(SCE_KOTLIN_DEFAULT); - } - else if (sc.state == SCE_KOTLIN_STRING && sc.ch == '\\') { + } else if (sc.ch == '\\' && sc.state != SCE_KOTLIN_RAWSTRING) { if (escSeq.resetEscapeState(sc.state, sc.chNext)) { sc.SetState(SCE_KOTLIN_ESCAPECHAR); sc.Forward(); } - } - else if (sc.ch == '$') { + } else if (sc.ch == '\'' && sc.state == SCE_KOTLIN_CHARACTER) { + sc.ForwardSetState(SCE_KOTLIN_DEFAULT); + } else if (sc.state != SCE_KOTLIN_CHARACTER) { + if (sc.ch == '$') { if (sc.chNext == '{') { nestedState.push_back(sc.state); sc.SetState(SCE_KOTLIN_OPERATOR2); sc.Forward(); - } - else if (IsIdentifierStartEx(sc.chNext)) { + } else if (IsIdentifierStartEx(sc.chNext)) { escSeq.outerState = sc.state; sc.SetState(SCE_KOTLIN_VARIABLE); } - } - else if (sc.ch == '\"' && (sc.state == SCE_KOTLIN_STRING || sc.MatchNext('"', '"'))) { + } else if (sc.ch == '\"' && (sc.state == SCE_KOTLIN_STRING || sc.MatchNext('"', '"'))) { if (sc.state == SCE_KOTLIN_RAWSTRING) { - sc.SetState(SCE_KOTLIN_RAWSTRINGEND); + //sc.Advance(2); sc.Forward(2); } sc.ForwardSetState(SCE_KOTLIN_DEFAULT); } - break; - - case SCE_KOTLIN_CHARACTER: - if (sc.atLineStart) { - sc.SetState(SCE_KOTLIN_DEFAULT); - } - else if (sc.ch == '\\') { - if (escSeq.resetEscapeState(sc.state, sc.chNext)) { - sc.SetState(SCE_KOTLIN_ESCAPECHAR); - sc.Forward(); - } - } - else if (sc.ch == '\'') { - sc.ForwardSetState(SCE_KOTLIN_DEFAULT); } break; @@ -523,18 +499,10 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, } break; - case SCE_KOTLIN_VARIABLE: - if (!IsIdentifierCharEx(sc.ch)) { - sc.SetState(escSeq.outerState); - continue; - } - break; - case SCE_KOTLIN_BACKTICKS: if (sc.atLineStart) { sc.SetState(SCE_KOTLIN_DEFAULT); - } - else if (sc.ch == '`') { + } else if (sc.ch == '`') { sc.ForwardSetState(SCE_KOTLIN_DEFAULT); } break; @@ -553,48 +521,41 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, if (visibleChars == 0) { lineStateLineType = KotlinLineStateMaskLineComment; } - } - else { + } else { commentLevel = 1; } continue; } if (sc.ch == '\"') { if (sc.MatchNext('"', '"')) { - sc.SetState(SCE_KOTLIN_RAWSTRINGSTART); + sc.SetState(SCE_KOTLIN_RAWSTRING); + //sc.Advance(2); sc.Forward(2); - sc.ForwardSetState(SCE_KOTLIN_RAWSTRING); - continue; - } + } else { sc.SetState(SCE_KOTLIN_STRING); } - else if (sc.ch == '\'') { + } else if (sc.ch == '\'') { sc.SetState(SCE_KOTLIN_CHARACTER); - } - else if (IsNumberStart(sc.ch, sc.chNext)) { + } else if (IsNumberStart(sc.ch, sc.chNext)) { sc.SetState(SCE_KOTLIN_NUMBER); - } - else if (sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) { - sc.SetState((kwType == SCE_KOTLIN_LABEL) ? SCE_KOTLIN_LABEL : SCE_KOTLIN_ANNOTATION); - kwType = SCE_KOTLIN_DEFAULT; - } - else if (sc.ch == '`') { + } else if (sc.ch == '@' && IsIdentifierStartEx(sc.chNext)) { + sc.SetState((kwType == KeywordType::Label) ? SCE_KOTLIN_LABEL : SCE_KOTLIN_ANNOTATION); + kwType = KeywordType::None; + } else if (sc.ch == '`') { sc.SetState(SCE_KOTLIN_BACKTICKS); - } - else if (IsIdentifierStartEx(sc.ch)) { - if (sc.chPrev != '.') { - chBeforeIdentifier = sc.chPrev; + } else if (IsIdentifierStartEx(sc.ch)) { + chBefore = chPrevNonWhite; + if (chPrevNonWhite != '.') { + chBeforeIdentifier = chPrevNonWhite; } sc.SetState(SCE_KOTLIN_IDENTIFIER); - } - else if (isoperator(sc.ch)) { - const bool interpolating = !nestedState.empty(); - sc.SetState(interpolating ? SCE_KOTLIN_OPERATOR2 : SCE_KOTLIN_OPERATOR); - if (interpolating) { + } else if (IsAGraphic(sc.ch)) { + sc.SetState(SCE_KOTLIN_OPERATOR); + if (!nestedState.empty()) { + sc.ChangeState(SCE_KOTLIN_OPERATOR2); if (sc.ch == '{') { nestedState.push_back(SCE_KOTLIN_DEFAULT); - } - else if (sc.ch == '}') { + } else if (sc.ch == '}') { const int outerState = TakeAndPop(nestedState); sc.ForwardSetState(outerState); continue; @@ -605,6 +566,9 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, if (!isspacechar(sc.ch)) { visibleChars++; + if (!IsSpaceEquiv(sc.state)) { + chPrevNonWhite = sc.ch; + } } if (sc.atLineEnd) { int lineState = (commentLevel << 2) | lineStateLineType; @@ -615,28 +579,21 @@ void SCI_METHOD LexerKotlin::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, lineStateLineType = 0; visibleChars = 0; visibleCharsBefore = 0; - kwType = SCE_KOTLIN_DEFAULT; + kwType = KeywordType::None; } sc.Forward(); } sc.Complete(); } -// ---------------------------------------------------------------------------- - - - - -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- struct FoldLineState { int lineComment; int packageImport; constexpr explicit FoldLineState(int lineState) noexcept : - lineComment(lineState& KotlinLineStateMaskLineComment), - packageImport(lineState& KotlinLineStateMaskImport) - { } + lineComment(lineState & KotlinLineStateMaskLineComment), + packageImport((lineState >> 1) & 1) { + } }; constexpr bool IsStreamCommentStyle(int style) noexcept { @@ -670,19 +627,19 @@ void SCI_METHOD LexerKotlin::Fold(Sci_PositionU startPos, Sci_Position lengthDoc int levelNext = levelCurrent; FoldLineState foldCurrent(styler.GetLineState(lineCurrent)); Sci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1); - Sci_PositionU lineEndPos = sci::min(lineStartNext, endPos) - 1; + lineStartNext = sci::min(lineStartNext, endPos); char chNext = styler[startPos]; int styleNext = styler.StyleAt(startPos); int style = styleNext; int visibleChars = 0; - for (Sci_PositionU i = startPos; i < endPos; i++) { + while (startPos < endPos) { const char ch = chNext; - chNext = styler.SafeGetCharAt(i + 1); const int stylePrev = style; style = styleNext; - styleNext = styler.StyleAt(i + 1); + chNext = styler[++startPos]; + styleNext = styler.StyleAt(startPos); switch (style) { case SCE_KOTLIN_COMMENTBLOCK: @@ -690,29 +647,26 @@ void SCI_METHOD LexerKotlin::Fold(Sci_PositionU startPos, Sci_Position lengthDoc const int level = (ch == '/' && chNext == '*') ? 1 : ((ch == '*' && chNext == '/') ? -1 : 0); if (level != 0) { levelNext += level; - i++; - chNext = styler.SafeGetCharAt(i + 1); - styleNext = styler.StyleAt(i + 1); + startPos++; + chNext = styler[startPos]; + styleNext = styler.StyleAt(startPos); } } break; - case SCE_KOTLIN_RAWSTRINGSTART: + case SCE_KOTLIN_RAWSTRING: if (style != stylePrev) { levelNext++; } - break; - - case SCE_KOTLIN_RAWSTRINGEND: if (style != styleNext) { levelNext--; } break; case SCE_KOTLIN_OPERATOR: + case SCE_KOTLIN_OPERATOR2: if (ch == '{' || ch == '[' || ch == '(') { levelNext++; - } - else if (ch == '}' || ch == ']' || ch == ')') { + } else if (ch == '}' || ch == ']' || ch == ')') { levelNext--; } break; @@ -721,20 +675,21 @@ void SCI_METHOD LexerKotlin::Fold(Sci_PositionU startPos, Sci_Position lengthDoc if (visibleChars == 0 && !IsSpaceEquiv(style)) { ++visibleChars; } - if (i == lineEndPos) { + if (startPos == lineStartNext) { const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1)); + levelNext = sci::max(levelNext, SC_FOLDLEVELBASE); if (foldCurrent.lineComment) { levelNext += foldNext.lineComment - foldPrev.lineComment; - } - else if (foldCurrent.packageImport) { + } else if (foldCurrent.packageImport) { levelNext += foldNext.packageImport - foldPrev.packageImport; - } - else if (visibleChars) { + } else if (visibleChars) { const Sci_PositionU bracePos = CheckBraceOnNextLine(styler, lineCurrent, SCE_KOTLIN_OPERATOR, SCE_KOTLIN_TASKMARKER); if (bracePos) { levelNext++; - i = bracePos; // skip the brace - chNext = '\0'; + startPos = bracePos + 1; // skip the brace + style = SCE_KOTLIN_OPERATOR; + chNext = styler[startPos]; + styleNext = styler.StyleAt(startPos); } } @@ -743,13 +698,11 @@ void SCI_METHOD LexerKotlin::Fold(Sci_PositionU startPos, Sci_Position lengthDoc if (levelUse < levelNext) { lev |= SC_FOLDLEVELHEADERFLAG; } - if (lev != styler.LevelAt(lineCurrent)) { styler.SetLevel(lineCurrent, lev); - } lineCurrent++; lineStartNext = styler.LineStart(lineCurrent + 1); - lineEndPos = sci::min(lineStartNext, endPos) - 1; + lineStartNext = sci::min(lineStartNext, endPos); levelCurrent = levelNext; foldPrev = foldCurrent; foldCurrent = foldNext; diff --git a/lexilla/lexers_x/SciX.iface b/lexilla/lexers_x/SciX.iface index dd3b1a2b9..01b1b0742 100644 --- a/lexilla/lexers_x/SciX.iface +++ b/lexilla/lexers_x/SciX.iface @@ -34,40 +34,39 @@ val SCE_AHK_WORD_UD=18 val SCE_AHK_VARREFKW=19 val SCE_AHK_ERROR=20 -# Lexical states for SCLEX_DART -lex Dart=SCLEX_DART SCE_DART_ + val SCE_DART_DEFAULT=0 val SCE_DART_COMMENTLINE=1 val SCE_DART_COMMENTLINEDOC=2 val SCE_DART_COMMENTBLOCK=3 val SCE_DART_COMMENTBLOCKDOC=4 -val SCE_DART_NUMBER=5 -val SCE_DART_OPERATOR=6 -val SCE_DART_OPERATOR2=7 +val SCE_DART_TASKMARKER=5 +val SCE_DART_VARIABLE2=6 +val SCE_DART_VARIABLE=7 val SCE_DART_IDENTIFIER=8 -val SCE_DART_STRING_SQ=9 -val SCE_DART_STRING_DQ=10 -val SCE_DART_TRIPLE_STRING_SQ=11 -val SCE_DART_TRIPLE_STRING_DQ=12 -val SCE_DART_ESCAPECHAR=13 -val SCE_DART_RAWSTRING_SQ=14 -val SCE_DART_RAWSTRING_DQ=15 -val SCE_DART_TRIPLE_RAWSTRING_SQ=16 -val SCE_DART_TRIPLE_RAWSTRING_DQ=17 -val SCE_DART_TRIPLE_STRING_SQSTART=18 -val SCE_DART_TRIPLE_STRING_DQSTART=19 -val SCE_DART_TRIPLE_STRING_SQEND=20 -val SCE_DART_TRIPLE_STRING_DQEND=21 -val SCE_DART_SYMBOL_OPERATOR=22 -val SCE_DART_SYMBOL_IDENTIFIER=23 -val SCE_DART_VARIABLE=24 -val SCE_DART_METADATA=25 -val SCE_DART_LABEL=26 -val SCE_DART_FUNCTION=27 -val SCE_DART_WORD=28 -val SCE_DART_WORD2=29 -val SCE_DART_CLASS=30 -val SCE_DART_ENUM=31 +val SCE_DART_SYMBOL_IDENTIFIER=9 +val SCE_DART_METADATA=10 +val SCE_DART_STRING_SQ=11 +val SCE_DART_STRING_DQ=12 +val SCE_DART_TRIPLE_STRING_SQ=13 +val SCE_DART_TRIPLE_STRING_DQ=14 +val SCE_DART_RAWSTRING_SQ=15 +val SCE_DART_RAWSTRING_DQ=16 +val SCE_DART_TRIPLE_RAWSTRING_SQ=17 +val SCE_DART_TRIPLE_RAWSTRING_DQ=18 +val SCE_DART_ESCAPECHAR=19 +val SCE_DART_OPERATOR=20 +val SCE_DART_OPERATOR2=21 +val SCE_DART_NUMBER=22 +val SCE_DART_SYMBOL_OPERATOR=23 +val SCE_DART_LABEL=24 +val SCE_DART_FUNCTION=25 +val SCE_DART_FUNCTION_DEFINITION=26 +val SCE_DART_WORD=27 +val SCE_DART_WORD2=28 +val SCE_DART_CLASS=29 +val SCE_DART_ENUM=30 +val SCE_DART_KEY=31 # Lexical states for SCLEX_KOTLIN @@ -78,25 +77,27 @@ val SCE_KOTLIN_COMMENTLINEDOC=2 val SCE_KOTLIN_COMMENTBLOCK=3 val SCE_KOTLIN_COMMENTBLOCKDOC=4 val SCE_KOTLIN_COMMENTDOCWORD=5 -val SCE_KOTLIN_STRING=6 -val SCE_KOTLIN_CHARACTER=7 -val SCE_KOTLIN_ESCAPECHAR=8 -val SCE_KOTLIN_RAWSTRING=9 -val SCE_KOTLIN_RAWSTRINGSTART=10 -val SCE_KOTLIN_RAWSTRINGEND=11 -val SCE_KOTLIN_BACKTICKS=12 -val SCE_KOTLIN_NUMBER=13 -val SCE_KOTLIN_OPERATOR=14 -val SCE_KOTLIN_OPERATOR2=15 -val SCE_KOTLIN_VARIABLE=16 -val SCE_KOTLIN_ANNOTATION=17 -val SCE_KOTLIN_LABEL=18 -val SCE_KOTLIN_IDENTIFIER=19 -val SCE_KOTLIN_WORD=20 -val SCE_KOTLIN_CLASS=21 -val SCE_KOTLIN_INTERFACE=22 -val SCE_KOTLIN_ENUM=23 -val SCE_KOTLIN_FUNCTION=24 +val SCE_KOTLIN_TASKMARKER=6 +val SCE_KOTLIN_NUMBER=7 +val SCE_KOTLIN_OPERATOR=8 +val SCE_KOTLIN_OPERATOR2=9 +val SCE_KOTLIN_CHARACTER=10 +val SCE_KOTLIN_STRING=11 +val SCE_KOTLIN_RAWSTRING=12 +val SCE_KOTLIN_ESCAPECHAR=13 +val SCE_KOTLIN_RAWSTRINGSTART=14 +val SCE_KOTLIN_RAWSTRINGEND=15 +val SCE_KOTLIN_BACKTICKS=16 +val SCE_KOTLIN_VARIABLE=17 +val SCE_KOTLIN_ANNOTATION=18 +val SCE_KOTLIN_LABEL=19 +val SCE_KOTLIN_IDENTIFIER=20 +val SCE_KOTLIN_WORD=21 +val SCE_KOTLIN_CLASS=22 +val SCE_KOTLIN_INTERFACE=23 +val SCE_KOTLIN_ENUM=24 +val SCE_KOTLIN_FUNCTION=25 +val SCE_KOTLIN_FUNCTION_DEFINITION=26 # Lexical states for SCLEX_TOML diff --git a/lexilla/lexers_x/SciXLexer.h b/lexilla/lexers_x/SciXLexer.h index d3ef0ebd1..548bf91f3 100644 --- a/lexilla/lexers_x/SciXLexer.h +++ b/lexilla/lexers_x/SciXLexer.h @@ -56,11 +56,11 @@ #define SCE_DART_COMMENTBLOCK 3 #define SCE_DART_COMMENTBLOCKDOC 4 #define SCE_DART_TASKMARKER 5 -#define SCE_DART_NUMBER 6 -#define SCE_DART_OPERATOR 7 -#define SCE_DART_OPERATOR2 8 -#define SCE_DART_IDENTIFIER 9 -#define SCE_DART_ESCAPECHAR 10 +#define SCE_DART_VARIABLE2 6 +#define SCE_DART_VARIABLE 7 +#define SCE_DART_IDENTIFIER 8 +#define SCE_DART_SYMBOL_IDENTIFIER 9 +#define SCE_DART_METADATA 10 #define SCE_DART_STRING_SQ 11 #define SCE_DART_STRING_DQ 12 #define SCE_DART_TRIPLE_STRING_SQ 13 @@ -69,18 +69,19 @@ #define SCE_DART_RAWSTRING_DQ 16 #define SCE_DART_TRIPLE_RAWSTRING_SQ 17 #define SCE_DART_TRIPLE_RAWSTRING_DQ 18 -#define SCE_DART_TRIPLE_STRINGSTART 19 -#define SCE_DART_TRIPLE_STRINGEND 20 +#define SCE_DART_ESCAPECHAR 19 +#define SCE_DART_OPERATOR 20 +#define SCE_DART_OPERATOR2 21 +#define SCE_DART_NUMBER 22 #define SCE_DART_SYMBOL_OPERATOR 23 -#define SCE_DART_SYMBOL_IDENTIFIER 24 -#define SCE_DART_VARIABLE 25 -#define SCE_DART_METADATA 26 -#define SCE_DART_LABEL 27 -#define SCE_DART_FUNCTION 28 -#define SCE_DART_WORD 29 -#define SCE_DART_WORD2 30 -#define SCE_DART_CLASS 31 -#define SCE_DART_ENUM 40 +#define SCE_DART_LABEL 24 +#define SCE_DART_FUNCTION 25 +#define SCE_DART_FUNCTION_DEFINITION 26 +#define SCE_DART_WORD 27 +#define SCE_DART_WORD2 28 +#define SCE_DART_CLASS 29 +#define SCE_DART_ENUM 30 +#define SCE_DART_KEY 31 #define SCE_KOTLIN_DEFAULT 0 @@ -97,18 +98,17 @@ #define SCE_KOTLIN_STRING 11 #define SCE_KOTLIN_RAWSTRING 12 #define SCE_KOTLIN_ESCAPECHAR 13 -#define SCE_KOTLIN_RAWSTRINGSTART 14 -#define SCE_KOTLIN_RAWSTRINGEND 15 -#define SCE_KOTLIN_BACKTICKS 16 -#define SCE_KOTLIN_VARIABLE 17 -#define SCE_KOTLIN_ANNOTATION 18 -#define SCE_KOTLIN_LABEL 19 -#define SCE_KOTLIN_IDENTIFIER 20 +#define SCE_KOTLIN_VARIABLE 14 +#define SCE_KOTLIN_LABEL 15 +#define SCE_KOTLIN_IDENTIFIER 16 +#define SCE_KOTLIN_ANNOTATION 17 +#define SCE_KOTLIN_BACKTICKS 18 #define SCE_KOTLIN_WORD 21 #define SCE_KOTLIN_CLASS 22 #define SCE_KOTLIN_INTERFACE 23 #define SCE_KOTLIN_ENUM 24 #define SCE_KOTLIN_FUNCTION 25 +#define SCE_KOTLIN_FUNCTION_DEFINITION 26 #define SCE_TOML_DEFAULT 0 diff --git a/lexilla/lexers_x/orig/zufuliu/LexDart.cxx b/lexilla/lexers_x/orig/zufuliu/LexDart.cxx index b509a778f..56a621d0e 100644 --- a/lexilla/lexers_x/orig/zufuliu/LexDart.cxx +++ b/lexilla/lexers_x/orig/zufuliu/LexDart.cxx @@ -85,6 +85,18 @@ constexpr bool IsSpaceEquiv(int state) noexcept { return state <= SCE_DART_TASKMARKER; } +constexpr bool IsTripleString(int state) noexcept { + return ((state - SCE_DART_STRING_SQ) & 3) > 1; +} + +constexpr int GetStringQuote(int state) noexcept { + if constexpr (SCE_DART_STRING_SQ & 1) { + return (state & 1) ? '\'' : '\"'; + } else { + return (state & 1) ? '\"' : '\''; + } +} + void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, LexerWordList keywordLists, Accessor &styler) { int lineStateLineType = 0; int commentLevel = 0; // nested block comment level @@ -98,6 +110,7 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt int chBefore = 0; int visibleCharsBefore = 0; int chPrevNonWhite = 0; + bool simpleStringInterpolation = false; EscapeSequence escSeq; StyleContext sc(startPos, lengthDoc, initStyle, styler); @@ -114,11 +127,16 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt if (lineState) { UnpackLineState(lineState, nestedState); } - } else if (startPos == 0 && sc.Match('#', '!')) { - // Shell Shebang at beginning of file - sc.SetState(SCE_DART_COMMENTLINE); - sc.Forward(); - lineStateLineType = DartLineStateMaskLineComment; + } + if (startPos == 0) { + if (sc.Match('#', '!')) { + // Shell Shebang at beginning of file + sc.SetState(SCE_DART_COMMENTLINE); + sc.Forward(); + lineStateLineType = DartLineStateMaskLineComment; + } + } else if (IsSpaceEquiv(initStyle)) { + LookbackNonWhite(styler, startPos, SCE_DART_TASKMARKER, chPrevNonWhite, initStyle); } while (sc.More()) { @@ -164,7 +182,7 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt if (visibleChars == sc.LengthCurrent()) { lineStateLineType = DartLineStateMaskImport; } - } else if (StrEqualsAny(s, "class", "extends", "implements", "new", "throw", "as", "is")) { + } else if (StrEqualsAny(s, "class", "extends", "implements", "new", "throw", "with", "as", "is", "on")) { kwType = KeywordType::Class; } else if (StrEqual(s, "enum")) { kwType = KeywordType::Enum; @@ -186,11 +204,10 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt } else if (keywordLists[KeywordIndex_Enumeration].InList(s)) { sc.ChangeState(SCE_DART_ENUM); } else if (sc.ch == ':') { - if (visibleChars == sc.LengthCurrent()) { - const int chNext = sc.GetLineNextChar(true); - if (IsJumpLabelNextChar(chNext)) { - sc.ChangeState(SCE_DART_LABEL); - } + if (chBefore == ',' || chBefore == '{') { + sc.ChangeState(SCE_DART_KEY); + } else if (IsJumpLabelPrevChar(chBefore)) { + sc.ChangeState(SCE_DART_LABEL); } } else if (sc.ch != '.') { if (kwType > KeywordType::None && kwType < KeywordType::Return) { @@ -211,6 +228,8 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt // type // type // type> + // type + // class type implements interface, interface {} // type identifier // type? identifier sc.ChangeState(SCE_DART_CLASS); @@ -258,32 +277,17 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt } break; - case SCE_DART_RAWSTRING_SQ: - case SCE_DART_RAWSTRING_DQ: - if (sc.atLineStart) { - sc.SetState(SCE_DART_DEFAULT); - } else if ((sc.state == SCE_DART_RAWSTRING_SQ && sc.ch == '\'') - || (sc.state == SCE_DART_RAWSTRING_DQ && sc.ch == '"')) { - sc.ForwardSetState(SCE_DART_DEFAULT); - } - break; - - case SCE_DART_TRIPLE_RAWSTRING_SQ: - case SCE_DART_TRIPLE_RAWSTRING_DQ: - if ((sc.state == SCE_DART_TRIPLE_RAWSTRING_SQ && sc.Match('\'', '\'', '\'')) - || (sc.state == SCE_DART_TRIPLE_RAWSTRING_DQ && sc.Match('"', '"', '"'))) { - sc.Advance(2); - sc.ForwardSetState(SCE_DART_DEFAULT); - } - break; - case SCE_DART_STRING_SQ: case SCE_DART_STRING_DQ: case SCE_DART_TRIPLE_STRING_SQ: case SCE_DART_TRIPLE_STRING_DQ: - if ((sc.state == SCE_DART_STRING_SQ || sc.state == SCE_DART_STRING_DQ) && sc.atLineStart) { + case SCE_DART_RAWSTRING_SQ: + case SCE_DART_RAWSTRING_DQ: + case SCE_DART_TRIPLE_RAWSTRING_SQ: + case SCE_DART_TRIPLE_RAWSTRING_DQ: + if (sc.atLineStart && !IsTripleString(sc.state)) { sc.SetState(SCE_DART_DEFAULT); - } else if (sc.ch == '\\') { + } else if (sc.ch == '\\' && sc.state < SCE_DART_RAWSTRING_SQ) { if (escSeq.resetEscapeState(sc.state, sc.chNext)) { sc.SetState(SCE_DART_ESCAPECHAR); sc.Forward(); @@ -293,21 +297,32 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt sc.Forward(); } } - } else if (sc.ch == '$') { - if (sc.chNext == '{') { - nestedState.push_back(sc.state); + } else if (sc.ch == '$' && sc.state < SCE_DART_RAWSTRING_SQ) { + if (sc.chNext == '{' || sc.chNext == '(') { + if (sc.chNext == '(') { + simpleStringInterpolation = true; + escSeq.outerState = sc.state; + } else { + nestedState.push_back(sc.state); + } sc.SetState(SCE_DART_OPERATOR2); sc.Forward(); } else if (IsIdentifierStartEx(sc.chNext)) { escSeq.outerState = sc.state; sc.SetState(SCE_DART_VARIABLE2); } - } else if ((sc.ch == '\'' && (sc.state == SCE_DART_STRING_SQ || (sc.state == SCE_DART_TRIPLE_STRING_SQ && sc.MatchNext('\'', '\'')))) - || (sc.ch == '"' && (sc.state == SCE_DART_STRING_DQ || (sc.state == SCE_DART_TRIPLE_STRING_DQ && sc.MatchNext('"', '"'))))) { - if (sc.state == SCE_DART_TRIPLE_STRING_SQ || sc.state == SCE_DART_TRIPLE_STRING_DQ) { + } else if (sc.ch == GetStringQuote(sc.state) && (!IsTripleString(sc.state) || sc.MatchNext())) { + if (IsTripleString(sc.state)) { sc.Advance(2); } - sc.ForwardSetState(SCE_DART_DEFAULT); + sc.Forward(); + if (sc.state <= SCE_DART_STRING_DQ && (chBefore == ',' || chBefore == '{')) { + const int chNext = sc.GetLineNextChar(); + if (chNext == ':') { + sc.ChangeState(SCE_DART_KEY); + } + } + sc.SetState(SCE_DART_DEFAULT); } break; @@ -357,6 +372,7 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt sc.SetState(SCE_DART_TRIPLE_STRING_DQ); sc.Advance(2); } else { + chBefore = chPrevNonWhite; sc.SetState(SCE_DART_STRING_DQ); } } else if (sc.ch == '\'') { @@ -364,6 +380,7 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt sc.SetState(SCE_DART_TRIPLE_STRING_SQ); sc.Advance(2); } else { + chBefore = chPrevNonWhite; sc.SetState(SCE_DART_STRING_SQ); } } else if (IsNumberStart(sc.ch, sc.chNext)) { @@ -382,16 +399,20 @@ void ColouriseDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initSt chBeforeIdentifier = chPrevNonWhite; } sc.SetState(SCE_DART_IDENTIFIER); - } else if (isoperator(sc.ch)) { + } else if (IsAGraphic(sc.ch)) { sc.SetState(SCE_DART_OPERATOR); + if (simpleStringInterpolation && sc.ch == ')') { + simpleStringInterpolation = false; + sc.ChangeState(SCE_DART_OPERATOR2); + sc.ForwardSetState(escSeq.outerState); + continue; + } if (!nestedState.empty()) { + sc.ChangeState(SCE_DART_OPERATOR2); if (sc.ch == '{') { nestedState.push_back(SCE_DART_DEFAULT); } else if (sc.ch == '}') { const int outerState = TakeAndPop(nestedState); - if (outerState != SCE_DART_DEFAULT) { - sc.ChangeState(SCE_DART_OPERATOR2); - } sc.ForwardSetState(outerState); continue; } @@ -431,15 +452,7 @@ struct FoldLineState { } }; -constexpr bool IsMultilineStringStyle(int style) noexcept { - return style == SCE_DART_TRIPLE_STRING_SQ - || style == SCE_DART_TRIPLE_STRING_DQ - || style == SCE_DART_OPERATOR2 - || style == SCE_DART_VARIABLE2 - || style == SCE_DART_ESCAPECHAR; -} - -void FoldDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, LexerWordList, Accessor &styler) { +void FoldDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, LexerWordList /*keywordLists*/, Accessor &styler) { const Sci_PositionU endPos = startPos + lengthDoc; Sci_Line lineCurrent = styler.GetLine(startPos); FoldLineState foldPrev(0); @@ -484,23 +497,18 @@ void FoldDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, case SCE_DART_TRIPLE_RAWSTRING_SQ: case SCE_DART_TRIPLE_RAWSTRING_DQ: - if (style != stylePrev) { - levelNext++; - } else if (style != styleNext) { - levelNext--; - } - break; - case SCE_DART_TRIPLE_STRING_SQ: case SCE_DART_TRIPLE_STRING_DQ: - if (!IsMultilineStringStyle(stylePrev)) { + if (style != stylePrev) { levelNext++; - } else if (!IsMultilineStringStyle(styleNext)) { + } + if (style != styleNext) { levelNext--; } break; case SCE_DART_OPERATOR: + case SCE_DART_OPERATOR2: if (ch == '{' || ch == '[' || ch == '(') { levelNext++; } else if (ch == '}' || ch == ']' || ch == ')') { @@ -514,6 +522,7 @@ void FoldDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, } if (startPos == lineStartNext) { const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1)); + levelNext = sci::max(levelNext, SC_FOLDLEVELBASE); if (foldCurrent.lineComment) { levelNext += foldNext.lineComment - foldPrev.lineComment; } else if (foldCurrent.packageImport) { @@ -534,9 +543,7 @@ void FoldDartDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, if (levelUse < levelNext) { lev |= SC_FOLDLEVELHEADERFLAG; } - if (lev != styler.LevelAt(lineCurrent)) { - styler.SetLevel(lineCurrent, lev); - } + styler.SetLevel(lineCurrent, lev); lineCurrent++; lineStartNext = styler.LineStart(lineCurrent + 1); diff --git a/lexilla/lexers_x/orig/zufuliu/LexKotlin.cxx b/lexilla/lexers_x/orig/zufuliu/LexKotlin.cxx index c23317e9b..e9b2361a8 100644 --- a/lexilla/lexers_x/orig/zufuliu/LexKotlin.cxx +++ b/lexilla/lexers_x/orig/zufuliu/LexKotlin.cxx @@ -53,9 +53,11 @@ enum { //KeywordIndex++Autogenerated -- start of section automatically generated enum { KeywordIndex_Keyword = 0, - KeywordIndex_Class = 1, - KeywordIndex_Interface = 2, - KeywordIndex_Enumeration = 3, + KeywordIndex_JavaClass = 1, + KeywordIndex_Class = 2, + KeywordIndex_JavaInterface = 3, + KeywordIndex_Interface = 4, + KeywordIndex_Enumeration = 5, }; //KeywordIndex--Autogenerated -- end of section automatically generated @@ -176,9 +178,9 @@ void ColouriseKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init } else if (sc.ch == '@') { sc.ChangeState(SCE_KOTLIN_LABEL); sc.Forward(); - } else if (keywordLists[KeywordIndex_Class].InList(s)) { + } else if (keywordLists[KeywordIndex_JavaClass].InList(s) || keywordLists[KeywordIndex_Class].InList(s)) { sc.ChangeState(SCE_KOTLIN_CLASS); - } else if (keywordLists[KeywordIndex_Interface].InList(s)) { + } else if (keywordLists[KeywordIndex_JavaInterface].InList(s) || keywordLists[KeywordIndex_Interface].InList(s)) { sc.ChangeState(SCE_KOTLIN_INTERFACE); } else if (keywordLists[KeywordIndex_Enumeration].InList(s)) { sc.ChangeState(SCE_KOTLIN_ENUM); @@ -202,6 +204,8 @@ void ColouriseKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init // type // type // type> + // type + // class type: type, interface {} sc.ChangeState(SCE_KOTLIN_CLASS); } } @@ -249,42 +253,34 @@ void ColouriseKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init } break; + case SCE_KOTLIN_CHARACTER: case SCE_KOTLIN_STRING: case SCE_KOTLIN_RAWSTRING: - if (sc.state == SCE_KOTLIN_STRING && sc.atLineStart) { + if (sc.atLineStart && sc.state != SCE_KOTLIN_RAWSTRING) { sc.SetState(SCE_KOTLIN_DEFAULT); - } else if (sc.state == SCE_KOTLIN_STRING && sc.ch == '\\') { + } else if (sc.ch == '\\' && sc.state != SCE_KOTLIN_RAWSTRING) { if (escSeq.resetEscapeState(sc.state, sc.chNext)) { sc.SetState(SCE_KOTLIN_ESCAPECHAR); sc.Forward(); } - } else if (sc.ch == '$') { - if (sc.chNext == '{') { - nestedState.push_back(sc.state); - sc.SetState(SCE_KOTLIN_OPERATOR2); - sc.Forward(); - } else if (IsIdentifierStartEx(sc.chNext)) { - escSeq.outerState = sc.state; - sc.SetState(SCE_KOTLIN_VARIABLE); - } - } else if (sc.ch == '\"' && (sc.state == SCE_KOTLIN_STRING || sc.MatchNext('"', '"'))) { - if (sc.state == SCE_KOTLIN_RAWSTRING) { - sc.Advance(2); - } + } else if (sc.ch == '\'' && sc.state == SCE_KOTLIN_CHARACTER) { sc.ForwardSetState(SCE_KOTLIN_DEFAULT); - } - break; - - case SCE_KOTLIN_CHARACTER: - if (sc.atLineStart) { - sc.SetState(SCE_KOTLIN_DEFAULT); - } else if (sc.ch == '\\') { - if (escSeq.resetEscapeState(sc.state, sc.chNext)) { - sc.SetState(SCE_KOTLIN_ESCAPECHAR); - sc.Forward(); + } else if (sc.state != SCE_KOTLIN_CHARACTER) { + if (sc.ch == '$') { + if (sc.chNext == '{') { + nestedState.push_back(sc.state); + sc.SetState(SCE_KOTLIN_OPERATOR2); + sc.Forward(); + } else if (IsIdentifierStartEx(sc.chNext)) { + escSeq.outerState = sc.state; + sc.SetState(SCE_KOTLIN_VARIABLE); + } + } else if (sc.ch == '\"' && (sc.state == SCE_KOTLIN_STRING || sc.MatchNext('"', '"'))) { + if (sc.state == SCE_KOTLIN_RAWSTRING) { + sc.Advance(2); + } + sc.ForwardSetState(SCE_KOTLIN_DEFAULT); } - } else if (sc.ch == '\'') { - sc.ForwardSetState(SCE_KOTLIN_DEFAULT); } break; @@ -344,16 +340,14 @@ void ColouriseKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int init chBeforeIdentifier = chPrevNonWhite; } sc.SetState(SCE_KOTLIN_IDENTIFIER); - } else if (isoperator(sc.ch)) { + } else if (IsAGraphic(sc.ch)) { sc.SetState(SCE_KOTLIN_OPERATOR); if (!nestedState.empty()) { + sc.ChangeState(SCE_KOTLIN_OPERATOR2); if (sc.ch == '{') { nestedState.push_back(SCE_KOTLIN_DEFAULT); } else if (sc.ch == '}') { const int outerState = TakeAndPop(nestedState); - if (outerState != SCE_KOTLIN_DEFAULT) { - sc.ChangeState(SCE_KOTLIN_OPERATOR2); - } sc.ForwardSetState(outerState); continue; } @@ -393,14 +387,7 @@ struct FoldLineState { } }; -constexpr bool IsMultilineStringStyle(int style) noexcept { - return style == SCE_KOTLIN_RAWSTRING - || style == SCE_KOTLIN_OPERATOR2 - || style == SCE_KOTLIN_ESCAPECHAR - || style == SCE_KOTLIN_VARIABLE; -} - -void FoldKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, LexerWordList, Accessor &styler) { +void FoldKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, LexerWordList /*keywordLists*/, Accessor &styler) { const Sci_PositionU endPos = startPos + lengthDoc; Sci_Line lineCurrent = styler.GetLine(startPos); FoldLineState foldPrev(0); @@ -444,14 +431,16 @@ void FoldKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle } break; case SCE_KOTLIN_RAWSTRING: - if (!IsMultilineStringStyle(stylePrev)) { + if (style != stylePrev) { levelNext++; - } else if (!IsMultilineStringStyle(styleNext)) { + } + if (style != styleNext) { levelNext--; } break; case SCE_KOTLIN_OPERATOR: + case SCE_KOTLIN_OPERATOR2: if (ch == '{' || ch == '[' || ch == '(') { levelNext++; } else if (ch == '}' || ch == ']' || ch == ')') { @@ -465,6 +454,7 @@ void FoldKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle } if (startPos == lineStartNext) { const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1)); + levelNext = sci::max(levelNext, SC_FOLDLEVELBASE); if (foldCurrent.lineComment) { levelNext += foldNext.lineComment - foldPrev.lineComment; } else if (foldCurrent.packageImport) { @@ -485,9 +475,7 @@ void FoldKotlinDoc(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle if (levelUse < levelNext) { lev |= SC_FOLDLEVELHEADERFLAG; } - if (lev != styler.LevelAt(lineCurrent)) { - styler.SetLevel(lineCurrent, lev); - } + styler.SetLevel(lineCurrent, lev); lineCurrent++; lineStartNext = styler.LineStart(lineCurrent + 1); diff --git a/lexilla/lexlib/StyleContext.h b/lexilla/lexlib/StyleContext.h index 0a6604379..600e6a42a 100644 --- a/lexilla/lexlib/StyleContext.h +++ b/lexilla/lexlib/StyleContext.h @@ -187,16 +187,61 @@ public: // >>>>>>>>>>>>>>> BEG NON STD SCI PATCH >>>>>>>>>>>>>>> - bool Match(char ch0, char ch1, char ch2) const noexcept { - return Match(ch0, ch1) && ch2 == styler.SafeGetCharAt(currentPos + 2); - } - bool MatchNext(char ch0, char ch1) const noexcept { - return chNext == static_cast(ch0) && ch1 == styler.SafeGetCharAt(currentPos + 2); - } + bool Match(char ch0, char ch1, char ch2) const noexcept { + return Match(ch0, ch1) && ch2 == styler.SafeGetCharAt(currentPos + 2); + } + + bool MatchNext() const noexcept { + return ch == chNext && ch == static_cast(styler[currentPos + 2]); + } + bool MatchNext(char ch0, char ch1) const noexcept { + return chNext == static_cast(ch0) && ch1 == styler.SafeGetCharAt(currentPos + 2); + } bool MatchNext(char ch0, char ch1, char ch2) const noexcept { return MatchNext(ch0, ch1) && ch2 == styler.SafeGetCharAt(currentPos + 3); } + constexpr bool IsWhiteSpace(int ch0) const noexcept { + return (ch0 == ' ') || ((ch0 >= 0x09) && (ch0 <= 0x0d)); + } + + int GetDocNextChar(bool ignoreCurrent = false) const noexcept { + if (!ignoreCurrent && !IsWhiteSpace(ch)) { + return ch; + } + if (!IsWhiteSpace(chNext)) { + return chNext; + } + // currentPos + width + widthNext + for (Sci_PositionU pos = currentPos + 2; ; pos++) { + const unsigned char chPos = styler[pos]; + if (!IsWhiteSpace(chPos)) { + return chPos; + } + } + } + + int GetLineNextChar(bool ignoreCurrent = false) const noexcept { + if (!ignoreCurrent && !IsWhiteSpace(ch)) { + return ch; + } + // currentPos + width for Unicode line ending + if (currentPos + 1 == static_cast(lineStartNext)) { + return '\0'; + } + if (!IsWhiteSpace(chNext)) { + return chNext; + } + // currentPos + width + widthNext + for (Sci_PositionU pos = currentPos + 2; pos < static_cast(lineStartNext); pos++) { + const unsigned char chPos = styler[pos]; + if (!IsWhiteSpace(chPos)) { + return chPos; + } + } + return '\0'; + } + // <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<< diff --git a/src/StyleLexers/styleLexDart.c b/src/StyleLexers/styleLexDart.c index 56166fefa..9f7c07ca9 100644 --- a/src/StyleLexers/styleLexDart.c +++ b/src/StyleLexers/styleLexDart.c @@ -6,36 +6,32 @@ KEYWORDLIST KeyWords_Dart = { // 0 keywords - "abstract as assert async await break case catch class const continue covariant default deferred do " + "abstract as assert async await base break case catch class const continue covariant default deferred do " "else enum export extends extension external factory false final finally for get hide " "if implements import in interface is late library mixin native new null of on operator part required rethrow return " - "set show static super switch sync this throw true try typedef var while with yield " + "sealed set show static super switch sync this throw true try typedef var when while with yield " - , // 1 keywords2 - "" + , // 1 types + "Function Never bool double dynamic int num void " - , // 2 types - "Function bool double dynamic int num void " - - , // 3 class - "BidirectionalIterator BigInt Comparable Comparator Completer " - "DateTime Deprecated Directory DoubleLinkedQueue DoubleLinkedQueueEntry Duration Error Exception Expando " - "File FileStat FileSystemEntity FileSystemEvent Future FutureOr HasNextIterator HashMap HashSet " - "IOException Invocation Iterable IterableBase IterableMixin Iterator " + , // 2 class + "BigInt Comparable Comparator Completer DateTime Deprecated Directory DoubleLinkedQueue Duration " + "Enum Error Exception Expando File FileLock FileMode FileStat FileSystemEntity FileSystemEvent Future FutureOr " + "HashMap HashSet IOException Invocation Iterable IterableBase IterableMixin Iterator " "LinkedHashMap LinkedHashSet LinkedList LinkedListEntry List ListBase ListMixin ListQueue " "Map MapBase MapEntry MapMixin MapView Match Null OSError Object Pattern Platform Point Process Queue " - "Random RawSocket RawSocketEvent Rectangle RegExp RegExpMatch RuneIterator Runes " + "Random RawSocket RawSocketEvent Record Rectangle RegExp RegExpMatch RuneIterator Runes " "ServerSocket Set SetBase SetMixin Sink Socket SocketException SplayTreeMap SplayTreeSet " "StackTrace Stopwatch Stream String StringBuffer StringSink Symbol SystemHash " - "Timer Type Uri UriData " + "Timer Type Uri UriData WeakReference " - , // 4 enum + , // 3 enumeration "" - , // 5 metadata + , // 4 metadata "Deprecated Since deprecated override patch pragma " - , // 6 function + , // 5 function "identical identityHashCode main print " , NULL @@ -58,7 +54,7 @@ EDITLEXER lexDart = { {MULTI_STYLE(SCE_DART_COMMENTBLOCKDOC, SCE_DART_COMMENTLINEDOC, 0, 0)}, IDS_LEX_STR_63259, L"Comment Doc", L"fore:#408040", L"" }, { {SCE_DART_TASKMARKER}, IDS_LEX_STR_63373, L"Task Marker", L"bold; fore:#408080" }, { {MULTI_STYLE(SCE_DART_STRING_SQ, SCE_DART_STRING_DQ, 0, 0)}, IDS_LEX_STR_String, L"String", L"fore:#008000", L"" }, - { {MULTI_STYLE(SCE_DART_TRIPLE_STRING_SQ, SCE_DART_TRIPLE_STRING_DQ, SCE_DART_TRIPLE_STRINGSTART, SCE_DART_TRIPLE_STRINGEND)}, IDS_LEX_STR_63385, L"TriQ-String", L"fore:#F08000", L"" }, + { {MULTI_STYLE(SCE_DART_TRIPLE_STRING_SQ, SCE_DART_TRIPLE_STRING_DQ, 0, 0)}, IDS_LEX_STR_63385, L"TriQ-String", L"fore:#F08000", L"" }, { {MULTI_STYLE(SCE_DART_RAWSTRING_SQ, SCE_DART_RAWSTRING_DQ, SCE_DART_TRIPLE_RAWSTRING_SQ, SCE_DART_TRIPLE_RAWSTRING_DQ)}, IDS_LEX_STR_VerbStrg, L"Verbatim String", L"fore:#F08000", L"" }, { {SCE_DART_ESCAPECHAR}, IDS_LEX_STR_63366, L"ESC Sequence", L"fore:#0080C0", L"" }, { {SCE_DART_LABEL}, IDS_LEX_STR_Label, L"Label", L"fore:#7C5AF3", L"" }, diff --git a/src/StyleLexers/styleLexKotlin.c b/src/StyleLexers/styleLexKotlin.c index 71c32d32e..cd6076cfc 100644 --- a/src/StyleLexers/styleLexKotlin.c +++ b/src/StyleLexers/styleLexKotlin.c @@ -5,81 +5,82 @@ //KEYWORDLIST KeyWords_Kotlin = EMPTY_KEYWORDLIST; KEYWORDLIST KeyWords_Kotlin = { - // 0 keywords + // 0 Keywords "abstract actual annotation as break by catch class companion const constructor continue crossinline " "data delegate do dynamic else enum expect external false field file final finally for fun get " "if import in infix init inline inner interface internal is it lateinit noinline null object open operator out override " "package param private property protected public receiver reified return sealed set setparam super suspend " - "tailrec this throw true try typealias typeof val var vararg when where while " + "tailrec this throw true try typealias typeof val value var vararg when where while " - , // 1 class - "AbstractCollection AbstractIterator AbstractList " - "AbstractMap AbstractMutableCollection AbstractMutableList AbstractMutableMap AbstractMutableSet AbstractQueue " - "AbstractSequentialList AbstractSet ActionBar Activity AdapterView AlertDialog Any Application " - "Array ArrayAdapter ArrayBlockingQueue ArrayDeque ArrayList Arrays " + , // 1 Java class + "AbstractCollection AbstractList AbstractMap AbstractQueue AbstractSequentialList AbstractSet ActionBar Activity " + "AdapterView AlertDialog Application Array ArrayAdapter ArrayBlockingQueue ArrayDeque ArrayList Arrays " "AtomicBoolean AtomicInteger AtomicLong AtomicReference AudioFormat AudioManager AudioRecord AudioTrack " - "Base64 BaseAdapter BigDecimal BigInteger Binder BitSet Bitmap Boolean BooleanArray " + "Base64 BaseAdapter BigDecimal BigInteger Binder BitSet Bitmap Boolean " "Buffer BufferedInputStream BufferedOutputStream BufferedReader BufferedWriter Build Bundle Button " - "Byte ByteArray ByteArrayInputStream ByteArrayOutputStream ByteBuffer ByteOrder " - "Calendar Canvas Char CharArray CharArrayReader CharArrayWriter CharBuffer Character Charset CheckBox ChoiceFormat " - "Class ClassLoader Collections Collectors Color " + "Byte ByteArrayInputStream ByteArrayOutputStream ByteBuffer ByteOrder " + "Calendar Canvas CharArrayReader CharArrayWriter CharBuffer Character Charset CheckBox ChoiceFormat Class ClassLoader " + "Collections Collectors Color " "ConcurrentHashMap ConcurrentLinkedDeque ConcurrentLinkedQueue Console Constructor Context ContextWrapper Copy " "CountDownLatch Currency " "DataInputStream DataOutputStream DatagramPacket DatagramSocket Date DateFormat DecimalFormat DeflaterOutputStream " - "Dialog Dictionary Display Double DoubleArray DoubleBuffer Drawable " + "Dialog Dictionary Display Double DoubleBuffer Drawable " "EOFException EditText Enum EnumMap EnumSet Environment Error EventObject Exception " "Field File FileDescriptor FileInputStream FileOutputStream FilePermission FileReader FileSystem FileWriter " - "FilterInputStream FilterOutputStream FilterReader FilterWriter Float FloatArray FloatBuffer Format Formatter " + "FilterInputStream FilterOutputStream FilterReader FilterWriter Float FloatBuffer Format Formatter " "GZIPInputStream GZIPOutputStream Gradle GregorianCalendar GridView " "Handler HashMap HashSet Hashtable HttpClient HttpCookie HttpRequest HttpURLConnection " - "IOError IOException Image ImageButton ImageView IndexedValue Inet4Address Inet6Address InetAddress InetSocketAddress " - "InflaterInputStream InputStream InputStreamReader Int IntArray IntBuffer Integer Intent IntentFilter " + "IOError IOException Image ImageButton ImageView Inet4Address Inet6Address InetAddress InetSocketAddress " + "InflaterInputStream InputStream InputStreamReader IntBuffer Integer Intent IntentFilter " "JarEntry JarException JarFile JarInputStream JarOutputStream JavaCompile KeyEvent " - "LayoutInflater LinearLayout LinkedHashMap LinkedHashSet LinkedList ListView Locale Long LongArray LongBuffer Looper " - "MappedByteBuffer MatchGroup Matcher Math Matrix Message MessageFormat Method Modifier Module MotionEvent " - "MulticastSocket " - "Nothing Notification Number NumberFormat " - "Object ObjectInputStream ObjectOutputStream Optional OutputStream OutputStreamWriter " - "Package Paint Pair Parcel Pattern PendingIntent PhantomReference " - "PipedInputStream PipedOutputStream PipedReader PipedWriter Point PointF " - "PrintStream PrintWriter PriorityQueue Process ProcessBuilder ProgressBar Project Properties " - "RadioButton RadioGroup Random " - "Reader Record Rect RectF Reference ReferenceQueue Regex Region RelativeLayout RemoteException Result " + "LayoutInflater LinearLayout LinkedHashMap LinkedHashSet LinkedList ListView Locale Long LongBuffer Looper " + "MappedByteBuffer Matcher Math Matrix Message MessageFormat Method Modifier Module MotionEvent MulticastSocket " + "Notification Number NumberFormat Object ObjectInputStream ObjectOutputStream Optional OutputStream OutputStreamWriter " + "Package Paint Parcel Pattern PendingIntent PhantomReference PipedInputStream PipedOutputStream PipedReader PipedWriter " + "Point PointF PrintStream PrintWriter PriorityQueue Process ProcessBuilder ProgressBar Project Properties " + "RadioButton RadioGroup Random Reader Record Rect RectF Reference ReferenceQueue Region RelativeLayout RemoteException " "Runtime RuntimeException " "Scanner Script ScrollView SearchView SecurityManager SeekBar Semaphore ServerSocket Service ServiceLoader Settings " - "Short ShortArray ShortBuffer SimpleDateFormat Socket SocketAddress SoftReference SourceSet Spinner " + "Short ShortBuffer SimpleDateFormat Socket SocketAddress SoftReference SourceSet Spinner " "Stack StackView String StringBuffer StringBuilder StringJoiner StringReader StringTokenizer StringWriter System " "TableLayout Task TextView Thread ThreadGroup ThreadLocal ThreadPoolExecutor Throwable TimeZone Timer TimerTask " - "Toast ToggleButton TreeMap TreeSet Triple " - "UByte UByteArray UInt UIntArray ULong ULongArray URI URL URLConnection URLDecoder URLEncoder UShort UShortArray UUID " - "Unit " - "Vector View ViewGroup Void WeakHashMap WeakReference Window Writer " + "Toast ToggleButton TreeMap TreeSet " + "URI URL URLConnection URLDecoder URLEncoder UUID Vector View ViewGroup Void WeakHashMap WeakReference Window Writer " "ZipEntry ZipException ZipFile ZipInputStream ZipOutputStream " - , // 2 interface + , // 2 class + "AbstractIterator AbstractMutableCollection AbstractMutableList AbstractMutableMap AbstractMutableSet Any " + "BooleanArray ByteArray Char CharArray DoubleArray FloatArray IndexedValue Int IntArray LongArray MatchGroup Nothing " + "Pair Regex Result ShortArray Triple UByte UByteArray UInt UIntArray ULong ULongArray UShort UShortArray Unit " + + , // 3 Java interface "Adapter Annotation Appendable AutoCloseable BaseStream BlockingDeque BlockingQueue ByteChannel " "Callable Channel CharSequence Cloneable Closeable Collection Collector Comparable Comparator ConcurrentMap Condition " "DataInput DataOutput Deque DoubleStream Enumeration EventListener Executor Flushable Formattable Function Future " - "Grouping HttpResponse IBinder IInterface IntStream Iterable Iterator Lazy List ListAdapter ListIterator Lock LongStream " - "Map MatchGroupCollection MatchResult Menu MenuItem " - "MutableCollection MutableIterable MutableIterator MutableList MutableListIterator MutableMap MutableSet " - "NavigableMap NavigableSet ObjectInput ObjectOutput OnClickListener Parcelable Path Predicate Queue " - "RandomAccess ReadWriteLock Readable Runnable Serializable Set SortedMap SortedSet Spliterator Stream WebSocket " + "HttpResponse IBinder IInterface IntStream Iterable Iterator List ListAdapter ListIterator Lock LongStream " + "Map MatchResult Menu MenuItem NavigableMap NavigableSet ObjectInput ObjectOutput OnClickListener " + "Parcelable Path Predicate Queue RandomAccess ReadWriteLock Readable Runnable " + "Serializable Set SortedMap SortedSet Spliterator Stream WebSocket " - , // 3 enum + , // 4 interface + "Grouping Lazy " + "MatchGroupCollection " + "MutableCollection MutableIterable MutableIterator MutableList MutableListIterator MutableMap MutableSet " + + , // 5 enumeration "AnnotationRetention AnnotationTarget DeprecationLevel ElementType LazyThreadSafetyMode RegexOption RetentionPolicy " "TimeUnit " - , // 4 annotation + , // 6 annotation "Basic Column Delegate DelegatesTo Deprecated Documented Entity FunctionalInterface Generated Id Inherited " "ManagedBean Metadata MustBeDocumented Native NonEmpty NonNull OrderBy OrderColumn Override " "PostConstruct PreDestroy Priority Readonly Repeatable ReplaceWith Resource Resources Retention " "SafeVarargs Serial Suppress SuppressWarnings Table Target Transient Version " - , // 5 function + , // 7 function "assert check error print println readLine require " - , // 6 KDoc + , // 8 KDoc "author constructor exception param property receiver return sample see since suppress throws " , NULL @@ -97,13 +98,13 @@ EDITLEXER lexKotlin = { { SCE_KOTLIN_CLASS }, IDS_LEX_STR_63258, L"Class", L"fore:#0080FF", L"" }, { { SCE_KOTLIN_INTERFACE }, IDS_LEX_STR_Interface, L"Interface", L"bold; fore:#1E90FF", L"" }, { { SCE_KOTLIN_ENUM }, IDS_LEX_STR_Enum, L"Enumeration", L"fore:#FF8000", L"" }, - { { SCE_KOTLIN_FUNCTION }, IDS_LEX_STR_63277, L"Function", L"fore:#A46000", L"" }, + { { MULTI_STYLE(SCE_KOTLIN_FUNCTION, SCE_KOTLIN_FUNCTION_DEFINITION, 0, 0) }, IDS_LEX_STR_63277, L"Function", L"fore:#A46000", L"" }, { { MULTI_STYLE(SCE_KOTLIN_COMMENTBLOCK, SCE_KOTLIN_COMMENTLINE, 0, 0) }, IDS_LEX_STR_Comment, L"Comment", L"fore:#608060", L"" }, { { MULTI_STYLE(SCE_KOTLIN_COMMENTBLOCKDOC, SCE_KOTLIN_COMMENTLINEDOC, 0, 0) }, IDS_LEX_STR_63259, L"Comment Doc", L"fore:#408080", L"" }, { { SCE_KOTLIN_COMMENTDOCWORD }, IDS_LEX_STR_63371, L"Comment Doc Word", L"fore:#408080", L"" }, { { SCE_KOTLIN_TASKMARKER }, IDS_LEX_STR_63373, L"Task Marker", L"bold; fore:#208080" }, { { MULTI_STYLE(SCE_KOTLIN_CHARACTER, SCE_KOTLIN_STRING, 0, 0) }, IDS_LEX_STR_String, L"String", L"fore:#008000", L"" }, - { { MULTI_STYLE(SCE_KOTLIN_RAWSTRING, SCE_KOTLIN_RAWSTRINGSTART, SCE_KOTLIN_RAWSTRINGEND, 0) }, IDS_LEX_STR_VerbStrg, L"Verbatim String", L"fore:#F08000", L"" }, + { { SCE_KOTLIN_RAWSTRING }, IDS_LEX_STR_VerbStrg, L"Verbatim String", L"fore:#F08000", L"" }, { { SCE_KOTLIN_ESCAPECHAR }, IDS_LEX_STR_63366, L"ESC Sequence", L"fore:#0080C0", L"" }, { { SCE_KOTLIN_BACKTICKS }, IDS_LEX_STR_63221, L"Back Ticks", L"fore:#9E4D2A", L"" }, { { SCE_KOTLIN_LABEL }, IDS_LEX_STR_Label, L"Label", L"fore:#7C5AF3", L"" },