+mrg: Merging Zufuliu's custom Lexers for Kotlin and Dart

This commit is contained in:
METANEOCORTEX\Kotti 2024-02-28 08:11:13 +01:00
parent ecca84b629
commit d98b8d0fea
10 changed files with 734 additions and 741 deletions

View File

@ -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,

View File

@ -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<int> 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?>
// 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<int>(kwType));
} else {
const int chNext = sc.GetDocNextChar(sc.ch == '?');
if (chNext == '(') {
// type method()
// type[] method()
// type<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?>
// type<type<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;

View File

@ -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<OptionsKotlin>
{
OptionSetKotlin()
@ -77,32 +80,31 @@ struct OptionSetKotlin : public OptionSet<OptionsKotlin>
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<int> 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<type?>
// 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<int>(kwType));
} else {
const int chNext = sc.GetDocNextChar(sc.ch == '?');
if (chNext == '(') {
// type function()
// type[] function()
// type<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?>
// type<type<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;

View File

@ -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

View File

@ -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

View File

@ -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?>
// type<type<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);

View File

@ -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?>
// type<type<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);

View File

@ -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<unsigned char>(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<unsigned char>(styler[currentPos + 2]);
}
bool MatchNext(char ch0, char ch1) const noexcept {
return chNext == static_cast<unsigned char>(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<Sci_PositionU>(lineStartNext)) {
return '\0';
}
if (!IsWhiteSpace(chNext)) {
return chNext;
}
// currentPos + width + widthNext
for (Sci_PositionU pos = currentPos + 2; pos < static_cast<Sci_PositionU>(lineStartNext); pos++) {
const unsigned char chPos = styler[pos];
if (!IsWhiteSpace(chPos)) {
return chPos;
}
}
return '\0';
}
// <<<<<<<<<<<<<<< END NON STD SCI PATCH <<<<<<<<<<<<<<<

View File

@ -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"" },

View File

@ -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"" },