chore: bump scintilla and lexilla version
This commit is contained in:
715
3rdparty/lexilla545/lexilla/lexers/LexDart.cxx
vendored
Normal file
715
3rdparty/lexilla545/lexilla/lexers/LexDart.cxx
vendored
Normal file
@ -0,0 +1,715 @@
|
||||
// Scintilla source code edit control
|
||||
/** @file LexDart.cxx
|
||||
** Lexer for Dart.
|
||||
**/
|
||||
// Based on Zufu Liu's Notepad4 Dart lexer
|
||||
// Modified for Scintilla by Jiri Techet, 2024
|
||||
// The License.txt file describes the conditions under which this software may be distributed.
|
||||
|
||||
#include <cassert>
|
||||
#include <cstring>
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <algorithm>
|
||||
|
||||
#include "ILexer.h"
|
||||
#include "Scintilla.h"
|
||||
#include "SciLexer.h"
|
||||
|
||||
#include "WordList.h"
|
||||
#include "LexAccessor.h"
|
||||
#include "Accessor.h"
|
||||
#include "StyleContext.h"
|
||||
#include "CharacterSet.h"
|
||||
#include "LexerModule.h"
|
||||
#include "OptionSet.h"
|
||||
#include "DefaultLexer.h"
|
||||
|
||||
using namespace Scintilla;
|
||||
using namespace Lexilla;
|
||||
|
||||
namespace {
|
||||
// Use an unnamed namespace to protect the functions and classes from name conflicts
|
||||
|
||||
constexpr bool IsEOLChar(int ch) noexcept {
|
||||
return ch == '\r' || ch == '\n';
|
||||
}
|
||||
|
||||
constexpr bool IsAGraphic(int ch) noexcept {
|
||||
// excludes C0 control characters and whitespace
|
||||
return ch > 32 && ch < 127;
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierChar(int ch) noexcept {
|
||||
return IsAlphaNumeric(ch) || ch == '_';
|
||||
}
|
||||
|
||||
constexpr bool IsIdentifierStart(int ch) noexcept {
|
||||
return IsUpperOrLowerCase(ch) || ch == '_';
|
||||
}
|
||||
|
||||
constexpr bool IsNumberContinue(int chPrev, int ch, int chNext) noexcept {
|
||||
return ((ch == '+' || ch == '-') && (chPrev == 'e' || chPrev == 'E'))
|
||||
|| (ch == '.' && chNext != '.');
|
||||
}
|
||||
|
||||
constexpr bool IsNumberStart(int ch, int chNext) noexcept {
|
||||
return IsADigit(ch) || (ch == '.' && IsADigit(chNext));
|
||||
}
|
||||
|
||||
constexpr bool IsDecimalNumber(int chPrev, int ch, int chNext) noexcept {
|
||||
return IsIdentifierChar(ch) || IsNumberContinue(chPrev, ch, chNext);
|
||||
}
|
||||
|
||||
struct EscapeSequence {
|
||||
int outerState = SCE_DART_DEFAULT;
|
||||
int digitsLeft = 0;
|
||||
bool brace = false;
|
||||
|
||||
// highlight any character as escape sequence.
|
||||
bool resetEscapeState(int state, int chNext) noexcept {
|
||||
if (IsEOLChar(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);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr bool IsDartIdentifierStart(int ch) noexcept {
|
||||
return IsIdentifierStart(ch) || ch == '$';
|
||||
}
|
||||
|
||||
constexpr bool IsDartIdentifierChar(int ch) noexcept {
|
||||
return IsIdentifierChar(ch) || ch == '$';
|
||||
}
|
||||
|
||||
constexpr bool IsDefinableOperator(int ch) noexcept {
|
||||
// https://github.com/dart-lang/sdk/blob/main/sdk/lib/core/symbol.dart
|
||||
return AnyOf(ch, '+', '-', '*', '/', '%', '~', '&', '|',
|
||||
'^', '<', '>', '=', '[', ']');
|
||||
}
|
||||
|
||||
constexpr bool IsSpaceEquiv(int state) noexcept {
|
||||
return state == SCE_DART_DEFAULT ||
|
||||
state == SCE_DART_COMMENTLINE ||
|
||||
state == SCE_DART_COMMENTLINEDOC ||
|
||||
state == SCE_DART_COMMENTBLOCK ||
|
||||
state == SCE_DART_COMMENTBLOCKDOC;
|
||||
}
|
||||
|
||||
constexpr bool IsTripleString(int state) noexcept {
|
||||
return state == SCE_DART_TRIPLE_STRING_SQ ||
|
||||
state == SCE_DART_TRIPLE_STRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_SQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
|
||||
}
|
||||
|
||||
constexpr bool IsDoubleQuoted(int state) noexcept {
|
||||
return state == SCE_DART_STRING_DQ ||
|
||||
state == SCE_DART_RAWSTRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_STRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
|
||||
}
|
||||
|
||||
constexpr bool IsRaw(int state) noexcept {
|
||||
return state == SCE_DART_RAWSTRING_SQ ||
|
||||
state == SCE_DART_RAWSTRING_DQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_SQ ||
|
||||
state == SCE_DART_TRIPLE_RAWSTRING_DQ;
|
||||
}
|
||||
|
||||
constexpr int GetStringQuote(int state) noexcept {
|
||||
return IsDoubleQuoted(state) ? '\"' : '\'';
|
||||
}
|
||||
|
||||
enum {
|
||||
DartLineStateMaskLineComment = 1, // line comment
|
||||
DartLineStateMaskImport = (1 << 1), // import
|
||||
DartLineStateMaskInterpolation = (1 << 2), // string interpolation
|
||||
};
|
||||
|
||||
// string interpolating state
|
||||
struct InterpolatingState {
|
||||
int state;
|
||||
int braceCount;
|
||||
};
|
||||
|
||||
struct FoldLineState {
|
||||
int lineComment;
|
||||
int packageImport;
|
||||
constexpr explicit FoldLineState(int lineState) noexcept:
|
||||
lineComment(lineState & DartLineStateMaskLineComment),
|
||||
packageImport((lineState >> 1) & 1) {
|
||||
}
|
||||
};
|
||||
|
||||
// Options used for LexerDart
|
||||
struct OptionsDart {
|
||||
bool fold = false;
|
||||
};
|
||||
|
||||
const char * const dartWordListDesc[] = {
|
||||
"Primary keywords",
|
||||
"Secondary keywords",
|
||||
"Tertiary keywords",
|
||||
"Global type definitions",
|
||||
nullptr
|
||||
};
|
||||
|
||||
struct OptionSetDart : public OptionSet<OptionsDart> {
|
||||
OptionSetDart() {
|
||||
DefineProperty("fold", &OptionsDart::fold);
|
||||
|
||||
DefineWordListSets(dartWordListDesc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
LexicalClass lexicalClasses[] = {
|
||||
// Lexer DART SCLEX_DART SCE_DART_:
|
||||
0, "SCE_DART_DEFAULT", "default", "White space",
|
||||
1, "SCE_DART_COMMENTLINE", "comment line", "Comment: //",
|
||||
2, "SCE_DART_COMMENTLINEDOC", "comment line documentation", "Comment: ///",
|
||||
3, "SCE_DART_COMMENTBLOCK", "comment", "Comment: /* */",
|
||||
4, "SCE_DART_COMMENTBLOCKDOC", "comment documentation", "Comment: /** */",
|
||||
5, "SCE_DART_STRING_SQ", "literal string", "Single quoted string",
|
||||
6, "SCE_DART_STRING_DQ", "literal string", "Double quoted string",
|
||||
7, "SCE_DART_TRIPLE_STRING_SQ", "literal string multiline", "Single quoted multiline string",
|
||||
8, "SCE_DART_TRIPLE_STRING_DQ", "literal string multiline", "Double quoted multiline string",
|
||||
9, "SCE_DART_RAWSTRING_SQ", "literal string raw", "Single quoted raw string",
|
||||
10, "SCE_DART_RAWSTRING_DQ", "literal string raw", "Double quoted raw string",
|
||||
11, "SCE_DART_TRIPLE_RAWSTRING_SQ", "literal string multiline raw", "Single quoted multiline raw string",
|
||||
12, "SCE_DART_TRIPLE_RAWSTRING_DQ", "literal string multiline raw", "Double quoted multiline raw string",
|
||||
13, "SCE_DART_ESCAPECHAR", "literal string escapesequence", "Escape sequence",
|
||||
14, "SCE_DART_IDENTIFIER", "identifier", "Identifier",
|
||||
15, "SCE_DART_IDENTIFIER_STRING", "identifier interpolated", "Identifier following $ inside strings",
|
||||
16, "SCE_DART_OPERATOR", "operator", "Operator",
|
||||
17, "SCE_DART_OPERATOR_STRING", "operator interpolated", "Braces following $ inside string",
|
||||
18, "SCE_DART_SYMBOL_IDENTIFIER", "identifier symbol", "Symbol name introduced by #",
|
||||
19, "SCE_DART_SYMBOL_OPERATOR", "operator symbol", "Operator introduced by #",
|
||||
20, "SCE_DART_NUMBER", "literal numeric", "Number",
|
||||
21, "SCE_DART_KEY", "key", "Keys preceding ':' and named parameters",
|
||||
22, "SCE_DART_METADATA", "preprocessor", "Metadata introduced by @",
|
||||
23, "SCE_DART_KW_PRIMARY", "keyword", "Primary keywords",
|
||||
24, "SCE_DART_KW_SECONDARY", "identifier", "Secondary keywords",
|
||||
25, "SCE_DART_KW_TERTIARY", "identifier", "Tertiary keywords",
|
||||
26, "SCE_DART_KW_TYPE", "identifier", "Global types",
|
||||
27, "SCE_DART_STRINGEOL", "error literal string", "End of line where string is not closed",
|
||||
};
|
||||
|
||||
class LexerDart : public DefaultLexer {
|
||||
WordList keywordsPrimary;
|
||||
WordList keywordsSecondary;
|
||||
WordList keywordsTertiary;
|
||||
WordList keywordsTypes;
|
||||
OptionsDart options;
|
||||
OptionSetDart osDart;
|
||||
public:
|
||||
LexerDart(const char *languageName_, int language_) :
|
||||
DefaultLexer(languageName_, language_, lexicalClasses, std::size(lexicalClasses)) {
|
||||
}
|
||||
// Deleted so LexerDart objects can not be copied.
|
||||
LexerDart(const LexerDart &) = delete;
|
||||
LexerDart(LexerDart &&) = delete;
|
||||
void operator=(const LexerDart &) = delete;
|
||||
void operator=(LexerDart &&) = delete;
|
||||
~LexerDart() override = default;
|
||||
|
||||
void SCI_METHOD Release() override {
|
||||
delete this;
|
||||
}
|
||||
int SCI_METHOD Version() const override {
|
||||
return lvRelease5;
|
||||
}
|
||||
const char *SCI_METHOD PropertyNames() override {
|
||||
return osDart.PropertyNames();
|
||||
}
|
||||
int SCI_METHOD PropertyType(const char *name) override {
|
||||
return osDart.PropertyType(name);
|
||||
}
|
||||
const char *SCI_METHOD DescribeProperty(const char *name) override {
|
||||
return osDart.DescribeProperty(name);
|
||||
}
|
||||
Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override;
|
||||
const char *SCI_METHOD PropertyGet(const char *key) override {
|
||||
return osDart.PropertyGet(key);
|
||||
}
|
||||
const char *SCI_METHOD DescribeWordListSets() override {
|
||||
return osDart.DescribeWordListSets();
|
||||
}
|
||||
Sci_Position SCI_METHOD WordListSet(int n, const char *wl) override;
|
||||
|
||||
void SCI_METHOD Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
void SCI_METHOD Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) override;
|
||||
|
||||
void *SCI_METHOD PrivateCall(int, void *) override {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle);
|
||||
Sci_PositionU LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite);
|
||||
|
||||
static ILexer5 *LexerFactoryDart() {
|
||||
return new LexerDart("dart", SCLEX_DART);
|
||||
}
|
||||
};
|
||||
|
||||
Sci_Position SCI_METHOD LexerDart::PropertySet(const char *key, const char *val) {
|
||||
if (osDart.PropertySet(&options, key, val)) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
Sci_Position SCI_METHOD LexerDart::WordListSet(int n, const char *wl) {
|
||||
WordList *wordListN = nullptr;
|
||||
switch (n) {
|
||||
case 0:
|
||||
wordListN = &keywordsPrimary;
|
||||
break;
|
||||
case 1:
|
||||
wordListN = &keywordsSecondary;
|
||||
break;
|
||||
case 2:
|
||||
wordListN = &keywordsTertiary;
|
||||
break;
|
||||
case 3:
|
||||
wordListN = &keywordsTypes;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
Sci_Position firstModification = -1;
|
||||
if (wordListN && wordListN->Set(wl, false)) {
|
||||
firstModification = 0;
|
||||
}
|
||||
return firstModification;
|
||||
}
|
||||
|
||||
void LexerDart::BacktrackToStart(const LexAccessor &styler, int stateMask, Sci_PositionU &startPos, Sci_Position &lengthDoc, int &initStyle) {
|
||||
const Sci_Position currentLine = styler.GetLine(startPos);
|
||||
if (currentLine != 0) {
|
||||
Sci_Position line = currentLine - 1;
|
||||
int lineState = styler.GetLineState(line);
|
||||
while ((lineState & stateMask) != 0 && line != 0) {
|
||||
--line;
|
||||
lineState = styler.GetLineState(line);
|
||||
}
|
||||
if ((lineState & stateMask) == 0) {
|
||||
++line;
|
||||
}
|
||||
if (line != currentLine) {
|
||||
const Sci_PositionU endPos = startPos + lengthDoc;
|
||||
startPos = (line == 0) ? 0 : styler.LineStart(line);
|
||||
lengthDoc = endPos - startPos;
|
||||
initStyle = (startPos == 0) ? 0 : styler.StyleAt(startPos - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Sci_PositionU LexerDart::LookbackNonWhite(LexAccessor &styler, Sci_PositionU startPos, int &chPrevNonWhite, int &stylePrevNonWhite) {
|
||||
do {
|
||||
--startPos;
|
||||
const unsigned style = styler.StyleAt(startPos);
|
||||
if (!IsSpaceEquiv(style)) {
|
||||
stylePrevNonWhite = style;
|
||||
chPrevNonWhite = static_cast<unsigned char>(styler[startPos]);
|
||||
break;
|
||||
}
|
||||
} while (startPos != 0);
|
||||
return startPos;
|
||||
}
|
||||
|
||||
void LexerDart::Lex(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
|
||||
Accessor styler(pAccess, nullptr);
|
||||
|
||||
int lineStateLineType = 0;
|
||||
int commentLevel = 0; // nested block comment level
|
||||
|
||||
std::vector<InterpolatingState> interpolatingStack;
|
||||
|
||||
int visibleChars = 0;
|
||||
int chBefore = 0;
|
||||
int chPrevNonWhite = 0;
|
||||
EscapeSequence escSeq;
|
||||
|
||||
if (initStyle == SCE_DART_STRINGEOL) {
|
||||
initStyle = SCE_DART_DEFAULT;
|
||||
}
|
||||
|
||||
if (startPos != 0) {
|
||||
// backtrack to the line where interpolation starts
|
||||
BacktrackToStart(styler, DartLineStateMaskInterpolation, startPos, lengthDoc, initStyle);
|
||||
}
|
||||
|
||||
StyleContext sc(startPos, lengthDoc, initStyle, styler);
|
||||
if (sc.currentLine > 0) {
|
||||
const int lineState = styler.GetLineState(sc.currentLine - 1);
|
||||
commentLevel = lineState >> 4;
|
||||
}
|
||||
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, chPrevNonWhite, initStyle);
|
||||
chBefore = chPrevNonWhite;
|
||||
}
|
||||
|
||||
while (sc.More()) {
|
||||
switch (sc.state) {
|
||||
case SCE_DART_OPERATOR:
|
||||
case SCE_DART_OPERATOR_STRING:
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
break;
|
||||
|
||||
case SCE_DART_NUMBER:
|
||||
if (!IsDecimalNumber(sc.chPrev, sc.ch, sc.chNext)) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_IDENTIFIER:
|
||||
case SCE_DART_IDENTIFIER_STRING:
|
||||
case SCE_DART_METADATA:
|
||||
case SCE_DART_SYMBOL_IDENTIFIER:
|
||||
if (!IsDartIdentifierChar(sc.ch) || (sc.ch == '$' && sc.state == SCE_DART_IDENTIFIER_STRING)) {
|
||||
if (sc.state == SCE_DART_METADATA || sc.state == SCE_DART_SYMBOL_IDENTIFIER) {
|
||||
if (sc.ch == '.') {
|
||||
const int state = sc.state;
|
||||
sc.SetState(SCE_DART_OPERATOR);
|
||||
sc.ForwardSetState(state);
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
char s[64];
|
||||
sc.GetCurrent(s, sizeof(s));
|
||||
const int state = sc.state;
|
||||
if (state == SCE_DART_IDENTIFIER_STRING) {
|
||||
sc.SetState(escSeq.outerState);
|
||||
continue;
|
||||
} else if (keywordsPrimary.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_PRIMARY);
|
||||
if (strcmp(s, "import") == 0 || strcmp(s, "part") == 0) {
|
||||
if (visibleChars == sc.LengthCurrent()) {
|
||||
lineStateLineType = DartLineStateMaskImport;
|
||||
}
|
||||
}
|
||||
} else if (keywordsSecondary.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_SECONDARY);
|
||||
} else if (keywordsTertiary.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_TERTIARY);
|
||||
} else if (keywordsTypes.InList(s)) {
|
||||
sc.ChangeState(SCE_DART_KW_TYPE);
|
||||
} else if (state == SCE_DART_IDENTIFIER && sc.ch == ':') {
|
||||
if (chBefore == ',' || chBefore == '{' || chBefore == '(') {
|
||||
sc.ChangeState(SCE_DART_KEY); // map key or named parameter
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_SYMBOL_OPERATOR:
|
||||
if (!IsDefinableOperator(sc.ch)) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_COMMENTLINE:
|
||||
case SCE_DART_COMMENTLINEDOC:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_COMMENTBLOCK:
|
||||
case SCE_DART_COMMENTBLOCKDOC:
|
||||
if (sc.Match('*', '/')) {
|
||||
sc.Forward();
|
||||
--commentLevel;
|
||||
if (commentLevel == 0) {
|
||||
sc.ForwardSetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
} else if (sc.Match('/', '*')) {
|
||||
sc.Forward();
|
||||
++commentLevel;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_STRING_SQ:
|
||||
case SCE_DART_STRING_DQ:
|
||||
case SCE_DART_TRIPLE_STRING_SQ:
|
||||
case SCE_DART_TRIPLE_STRING_DQ:
|
||||
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.atLineEnd && !IsTripleString(sc.state)) {
|
||||
sc.ChangeState(SCE_DART_STRINGEOL);
|
||||
} else if (sc.ch == '\\' && !IsRaw(sc.state)) {
|
||||
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 == '$' && !IsRaw(sc.state)) {
|
||||
escSeq.outerState = sc.state;
|
||||
sc.SetState(SCE_DART_OPERATOR_STRING);
|
||||
sc.Forward();
|
||||
if (sc.ch == '{') {
|
||||
interpolatingStack.push_back({escSeq.outerState, 1});
|
||||
} else if (sc.ch != '$' && IsDartIdentifierStart(sc.ch)) {
|
||||
sc.SetState(SCE_DART_IDENTIFIER_STRING);
|
||||
} else { // error
|
||||
sc.SetState(escSeq.outerState);
|
||||
continue;
|
||||
}
|
||||
} else if (sc.ch == GetStringQuote(sc.state) &&
|
||||
(!IsTripleString(sc.state) || (sc.Match(IsDoubleQuoted(sc.state) ? R"(""")" : R"(''')")))) {
|
||||
if (IsTripleString(sc.state)) {
|
||||
sc.Forward(2);
|
||||
}
|
||||
sc.Forward();
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_STRINGEOL:
|
||||
if (sc.atLineStart) {
|
||||
sc.SetState(SCE_DART_DEFAULT);
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_ESCAPECHAR:
|
||||
if (escSeq.atEscapeEnd(sc.ch)) {
|
||||
if (escSeq.brace && sc.ch == '}') {
|
||||
sc.Forward();
|
||||
}
|
||||
sc.SetState(escSeq.outerState);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc.state == SCE_DART_DEFAULT) {
|
||||
if (sc.ch == '/' && (sc.chNext == '/' || sc.chNext == '*')) {
|
||||
const int chNext = sc.chNext;
|
||||
sc.SetState((chNext == '/') ? SCE_DART_COMMENTLINE : SCE_DART_COMMENTBLOCK);
|
||||
sc.Forward(2);
|
||||
if (sc.ch == chNext && sc.chNext != chNext) {
|
||||
if (sc.state == SCE_DART_COMMENTLINE) {
|
||||
sc.ChangeState(SCE_DART_COMMENTLINEDOC);
|
||||
} else {
|
||||
sc.ChangeState(SCE_DART_COMMENTBLOCKDOC);
|
||||
}
|
||||
}
|
||||
if (chNext == '/') {
|
||||
if (visibleChars == 0) {
|
||||
lineStateLineType = DartLineStateMaskLineComment;
|
||||
}
|
||||
} else {
|
||||
commentLevel = 1;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sc.ch == 'r' && (sc.chNext == '\'' || sc.chNext == '"')) {
|
||||
sc.SetState((sc.chNext == '\'') ? SCE_DART_RAWSTRING_SQ : SCE_DART_RAWSTRING_DQ);
|
||||
sc.Forward(2);
|
||||
if (sc.chPrev == '\'' && sc.Match('\'', '\'')) {
|
||||
sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_SQ);
|
||||
sc.Forward(2);
|
||||
} else if (sc.chPrev == '"' && sc.Match('"', '"')) {
|
||||
sc.ChangeState(SCE_DART_TRIPLE_RAWSTRING_DQ);
|
||||
sc.Forward(2);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (sc.ch == '"') {
|
||||
if (sc.Match(R"(""")")) {
|
||||
sc.SetState(SCE_DART_TRIPLE_STRING_DQ);
|
||||
sc.Forward(2);
|
||||
} else {
|
||||
chBefore = chPrevNonWhite;
|
||||
sc.SetState(SCE_DART_STRING_DQ);
|
||||
}
|
||||
} else if (sc.ch == '\'') {
|
||||
if (sc.Match(R"(''')")) {
|
||||
sc.SetState(SCE_DART_TRIPLE_STRING_SQ);
|
||||
sc.Forward(2);
|
||||
} else {
|
||||
chBefore = chPrevNonWhite;
|
||||
sc.SetState(SCE_DART_STRING_SQ);
|
||||
}
|
||||
} else if (IsNumberStart(sc.ch, sc.chNext)) {
|
||||
sc.SetState(SCE_DART_NUMBER);
|
||||
} else if ((sc.ch == '@' || sc.ch == '#') && IsDartIdentifierStart(sc.chNext)) {
|
||||
sc.SetState((sc.ch == '@') ? SCE_DART_METADATA : SCE_DART_SYMBOL_IDENTIFIER);
|
||||
} else if (IsDartIdentifierStart(sc.ch)) {
|
||||
chBefore = chPrevNonWhite;
|
||||
sc.SetState(SCE_DART_IDENTIFIER);
|
||||
} else if (sc.ch == '#' && IsDefinableOperator(sc.chNext)) {
|
||||
sc.SetState(SCE_DART_SYMBOL_OPERATOR);
|
||||
} else if (IsAGraphic(sc.ch)) {
|
||||
sc.SetState(SCE_DART_OPERATOR);
|
||||
if (!interpolatingStack.empty() && AnyOf(sc.ch, '{', '}')) {
|
||||
InterpolatingState ¤t = interpolatingStack.back();
|
||||
if (sc.ch == '{') {
|
||||
current.braceCount += 1;
|
||||
} else {
|
||||
current.braceCount -= 1;
|
||||
if (current.braceCount == 0) {
|
||||
sc.ChangeState(SCE_DART_OPERATOR_STRING);
|
||||
sc.ForwardSetState(current.state);
|
||||
interpolatingStack.pop_back();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isspacechar(sc.ch)) {
|
||||
visibleChars++;
|
||||
if (!IsSpaceEquiv(sc.state)) {
|
||||
chPrevNonWhite = sc.ch;
|
||||
}
|
||||
}
|
||||
if (sc.atLineEnd) {
|
||||
int lineState = (commentLevel << 4) | lineStateLineType;
|
||||
if (!interpolatingStack.empty()) {
|
||||
lineState |= DartLineStateMaskInterpolation;
|
||||
}
|
||||
styler.SetLineState(sc.currentLine, lineState);
|
||||
lineStateLineType = 0;
|
||||
visibleChars = 0;
|
||||
}
|
||||
sc.Forward();
|
||||
}
|
||||
|
||||
sc.Complete();
|
||||
}
|
||||
|
||||
void LexerDart::Fold(Sci_PositionU startPos, Sci_Position lengthDoc, int initStyle, IDocument *pAccess) {
|
||||
if (!options.fold)
|
||||
return;
|
||||
|
||||
Accessor styler(pAccess, nullptr);
|
||||
const Sci_PositionU endPos = startPos + lengthDoc;
|
||||
Sci_Position lineCurrent = styler.GetLine(startPos);
|
||||
while (lineCurrent > 0) {
|
||||
lineCurrent--;
|
||||
startPos = styler.LineStart(lineCurrent);
|
||||
initStyle = (startPos > 0) ? styler.StyleIndexAt(startPos) : 0;
|
||||
if (initStyle != SCE_DART_COMMENTBLOCKDOC && initStyle != SCE_DART_COMMENTBLOCK &&
|
||||
initStyle != SCE_DART_TRIPLE_RAWSTRING_SQ && initStyle != SCE_DART_TRIPLE_RAWSTRING_DQ &&
|
||||
initStyle != SCE_DART_TRIPLE_STRING_SQ && initStyle != SCE_DART_TRIPLE_STRING_DQ)
|
||||
break;
|
||||
}
|
||||
FoldLineState foldPrev(0);
|
||||
int levelCurrent = SC_FOLDLEVELBASE;
|
||||
if (lineCurrent > 0) {
|
||||
levelCurrent = styler.LevelAt(lineCurrent - 1) >> 16;
|
||||
foldPrev = FoldLineState(styler.GetLineState(lineCurrent - 1));
|
||||
}
|
||||
|
||||
int levelNext = levelCurrent;
|
||||
FoldLineState foldCurrent(styler.GetLineState(lineCurrent));
|
||||
Sci_PositionU lineStartNext = styler.LineStart(lineCurrent + 1);
|
||||
lineStartNext = std::min(lineStartNext, endPos);
|
||||
|
||||
char chNext = styler[startPos];
|
||||
int styleNext = styler.StyleIndexAt(startPos);
|
||||
int style = initStyle;
|
||||
|
||||
while (startPos < endPos) {
|
||||
const char ch = chNext;
|
||||
const int stylePrev = style;
|
||||
style = styleNext;
|
||||
chNext = styler[++startPos];
|
||||
styleNext = styler.StyleIndexAt(startPos);
|
||||
|
||||
switch (style) {
|
||||
case SCE_DART_COMMENTBLOCKDOC:
|
||||
case SCE_DART_COMMENTBLOCK: {
|
||||
const int level = (ch == '/' && chNext == '*') ? 1 : ((ch == '*' && chNext == '/') ? -1 : 0);
|
||||
if (level != 0) {
|
||||
levelNext += level;
|
||||
startPos++;
|
||||
chNext = styler[startPos];
|
||||
styleNext = styler.StyleIndexAt(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 && !AnyOf(stylePrev, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {
|
||||
levelNext++;
|
||||
}
|
||||
if (style != styleNext && !AnyOf(styleNext, SCE_DART_ESCAPECHAR, SCE_DART_OPERATOR_STRING, SCE_DART_IDENTIFIER_STRING)) {
|
||||
levelNext--;
|
||||
}
|
||||
break;
|
||||
|
||||
case SCE_DART_OPERATOR:
|
||||
case SCE_DART_OPERATOR_STRING:
|
||||
if (ch == '{' || ch == '[' || ch == '(') {
|
||||
levelNext++;
|
||||
} else if (ch == '}' || ch == ']' || ch == ')') {
|
||||
levelNext--;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (startPos == lineStartNext) {
|
||||
const FoldLineState foldNext(styler.GetLineState(lineCurrent + 1));
|
||||
levelNext = std::max(levelNext, SC_FOLDLEVELBASE);
|
||||
if (foldCurrent.lineComment) {
|
||||
levelNext += foldNext.lineComment - foldPrev.lineComment;
|
||||
} else if (foldCurrent.packageImport) {
|
||||
levelNext += foldNext.packageImport - foldPrev.packageImport;
|
||||
}
|
||||
|
||||
const int levelUse = levelCurrent;
|
||||
int lev = levelUse | (levelNext << 16);
|
||||
if (levelUse < levelNext) {
|
||||
lev |= SC_FOLDLEVELHEADERFLAG;
|
||||
}
|
||||
styler.SetLevel(lineCurrent, lev);
|
||||
|
||||
lineCurrent++;
|
||||
lineStartNext = styler.LineStart(lineCurrent + 1);
|
||||
lineStartNext = std::min(lineStartNext, endPos);
|
||||
levelCurrent = levelNext;
|
||||
foldPrev = foldCurrent;
|
||||
foldCurrent = foldNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // unnamed namespace end
|
||||
|
||||
extern const LexerModule lmDart(SCLEX_DART, LexerDart::LexerFactoryDart, "dart", dartWordListDesc);
|
Reference in New Issue
Block a user