diff options
Diffstat (limited to 'lexers/LexRust.cxx')
| -rw-r--r-- | lexers/LexRust.cxx | 844 | 
1 files changed, 0 insertions, 844 deletions
| diff --git a/lexers/LexRust.cxx b/lexers/LexRust.cxx deleted file mode 100644 index 439d2d3b0..000000000 --- a/lexers/LexRust.cxx +++ /dev/null @@ -1,844 +0,0 @@ -/** @file LexRust.cxx - ** Lexer for Rust. - ** - ** Copyright (c) 2013 by SiegeLord <slabode@aim.com> - ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net> - **/ -// Copyright 1998-2005 by Neil Hodgson <neilh@scintilla.org> -// The License.txt file describes the conditions under which this software may be distributed. - -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <stdarg.h> -#include <assert.h> -#include <ctype.h> - -#include <string> -#include <map> - -#include "ILexer.h" -#include "Scintilla.h" -#include "SciLexer.h" - -#include "PropSetSimple.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; - -static const int NUM_RUST_KEYWORD_LISTS = 7; -static const int MAX_RUST_IDENT_CHARS = 1023; - -static bool IsStreamCommentStyle(int style) { -	return style == SCE_RUST_COMMENTBLOCK || -		   style == SCE_RUST_COMMENTBLOCKDOC; -} - -// Options used for LexerRust -struct OptionsRust { -	bool fold; -	bool foldSyntaxBased; -	bool foldComment; -	bool foldCommentMultiline; -	bool foldCommentExplicit; -	std::string foldExplicitStart; -	std::string foldExplicitEnd; -	bool foldExplicitAnywhere; -	bool foldCompact; -	int  foldAtElseInt; -	bool foldAtElse; -	OptionsRust() { -		fold = false; -		foldSyntaxBased = true; -		foldComment = false; -		foldCommentMultiline = true; -		foldCommentExplicit = true; -		foldExplicitStart = ""; -		foldExplicitEnd   = ""; -		foldExplicitAnywhere = false; -		foldCompact = true; -		foldAtElseInt = -1; -		foldAtElse = false; -	} -}; - -static const char * const rustWordLists[NUM_RUST_KEYWORD_LISTS + 1] = { -			"Primary keywords and identifiers", -			"Built in types", -			"Other keywords", -			"Keywords 4", -			"Keywords 5", -			"Keywords 6", -			"Keywords 7", -			0, -		}; - -struct OptionSetRust : public OptionSet<OptionsRust> { -	OptionSetRust() { -		DefineProperty("fold", &OptionsRust::fold); - -		DefineProperty("fold.comment", &OptionsRust::foldComment); - -		DefineProperty("fold.compact", &OptionsRust::foldCompact); - -		DefineProperty("fold.at.else", &OptionsRust::foldAtElse); - -		DefineProperty("fold.rust.syntax.based", &OptionsRust::foldSyntaxBased, -			"Set this property to 0 to disable syntax based folding."); - -		DefineProperty("fold.rust.comment.multiline", &OptionsRust::foldCommentMultiline, -			"Set this property to 0 to disable folding multi-line comments when fold.comment=1."); - -		DefineProperty("fold.rust.comment.explicit", &OptionsRust::foldCommentExplicit, -			"Set this property to 0 to disable folding explicit fold points when fold.comment=1."); - -		DefineProperty("fold.rust.explicit.start", &OptionsRust::foldExplicitStart, -			"The string to use for explicit fold start points, replacing the standard //{."); - -		DefineProperty("fold.rust.explicit.end", &OptionsRust::foldExplicitEnd, -			"The string to use for explicit fold end points, replacing the standard //}."); - -		DefineProperty("fold.rust.explicit.anywhere", &OptionsRust::foldExplicitAnywhere, -			"Set this property to 1 to enable explicit fold points anywhere, not just in line comments."); - -		DefineProperty("lexer.rust.fold.at.else", &OptionsRust::foldAtElseInt, -			"This option enables Rust folding on a \"} else {\" line of an if statement."); - -		DefineWordListSets(rustWordLists); -	} -}; - -class LexerRust : public DefaultLexer { -	WordList keywords[NUM_RUST_KEYWORD_LISTS]; -	OptionsRust options; -	OptionSetRust osRust; -public: -	LexerRust() : DefaultLexer("rust", SCLEX_RUST) { -	} -	virtual ~LexerRust() { -	} -	void SCI_METHOD Release() override { -		delete this; -	} -	int SCI_METHOD Version() const override { -		return lvRelease5; -	} -	const char * SCI_METHOD PropertyNames() override { -		return osRust.PropertyNames(); -	} -	int SCI_METHOD PropertyType(const char *name) override { -		return osRust.PropertyType(name); -	} -	const char * SCI_METHOD DescribeProperty(const char *name) override { -		return osRust.DescribeProperty(name); -	} -	Sci_Position SCI_METHOD PropertySet(const char *key, const char *val) override; -	const char * SCI_METHOD PropertyGet(const char *key) override { -		return osRust.PropertyGet(key); -	} -	const char * SCI_METHOD DescribeWordListSets() override { -		return osRust.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 0; -	} -	static ILexer5 *LexerFactoryRust() { -		return new LexerRust(); -	} -}; - -Sci_Position SCI_METHOD LexerRust::PropertySet(const char *key, const char *val) { -	if (osRust.PropertySet(&options, key, val)) { -		return 0; -	} -	return -1; -} - -Sci_Position SCI_METHOD LexerRust::WordListSet(int n, const char *wl) { -	Sci_Position firstModification = -1; -	if (n < NUM_RUST_KEYWORD_LISTS) { -		WordList *wordListN = &keywords[n]; -		WordList wlNew; -		wlNew.Set(wl); -		if (*wordListN != wlNew) { -			wordListN->Set(wl); -			firstModification = 0; -		} -	} -	return firstModification; -} - -static bool IsWhitespace(int c) { -    return c == ' ' || c == '\t' || c == '\r' || c == '\n'; -} - -/* This isn't quite right for Unicode identifiers */ -static bool IsIdentifierStart(int ch) { -	return (IsASCII(ch) && (isalpha(ch) || ch == '_')) || !IsASCII(ch); -} - -/* This isn't quite right for Unicode identifiers */ -static bool IsIdentifierContinue(int ch) { -	return (IsASCII(ch) && (isalnum(ch) || ch == '_')) || !IsASCII(ch); -} - -static void ScanWhitespace(Accessor& styler, Sci_Position& pos, Sci_Position max) { -	while (IsWhitespace(styler.SafeGetCharAt(pos, '\0')) && pos < max) { -		if (pos == styler.LineEnd(styler.GetLine(pos))) -			styler.SetLineState(styler.GetLine(pos), 0); -		pos++; -	} -	styler.ColourTo(pos-1, SCE_RUST_DEFAULT); -} - -static void GrabString(char* s, Accessor& styler, Sci_Position start, Sci_Position len) { -	for (Sci_Position ii = 0; ii < len; ii++) -		s[ii] = styler[ii + start]; -	s[len] = '\0'; -} - -static void ScanIdentifier(Accessor& styler, Sci_Position& pos, WordList *keywords) { -	Sci_Position start = pos; -	while (IsIdentifierContinue(styler.SafeGetCharAt(pos, '\0'))) -		pos++; - -	if (styler.SafeGetCharAt(pos, '\0') == '!') { -		pos++; -		styler.ColourTo(pos - 1, SCE_RUST_MACRO); -	} else { -		char s[MAX_RUST_IDENT_CHARS + 1]; -		Sci_Position len = pos - start; -		len = len > MAX_RUST_IDENT_CHARS ? MAX_RUST_IDENT_CHARS : len; -		GrabString(s, styler, start, len); -		bool keyword = false; -		for (int ii = 0; ii < NUM_RUST_KEYWORD_LISTS; ii++) { -			if (keywords[ii].InList(s)) { -				styler.ColourTo(pos - 1, SCE_RUST_WORD + ii); -				keyword = true; -				break; -			} -		} -		if (!keyword) { -			styler.ColourTo(pos - 1, SCE_RUST_IDENTIFIER); -		} -	} -} - -/* Scans a sequence of digits, returning true if it found any. */ -static bool ScanDigits(Accessor& styler, Sci_Position& pos, int base) { -	Sci_Position old_pos = pos; -	for (;;) { -		int c = styler.SafeGetCharAt(pos, '\0'); -		if (IsADigit(c, base) || c == '_') -			pos++; -		else -			break; -	} -	return old_pos != pos; -} - -/* Scans an integer and floating point literals. */ -static void ScanNumber(Accessor& styler, Sci_Position& pos) { -	int base = 10; -	int c = styler.SafeGetCharAt(pos, '\0'); -	int n = styler.SafeGetCharAt(pos + 1, '\0'); -	bool error = false; -	/* Scan the prefix, thus determining the base. -	 * 10 is default if there's no prefix. */ -	if (c == '0' && n == 'x') { -		pos += 2; -		base = 16; -	} else if (c == '0' && n == 'b') { -		pos += 2; -		base = 2; -	} else if (c == '0' && n == 'o') { -		pos += 2; -		base = 8; -	} - -	/* Scan initial digits. The literal is malformed if there are none. */ -	error |= !ScanDigits(styler, pos, base); -	/* See if there's an integer suffix. We mimic the Rust's lexer -	 * and munch it even if there was an error above. */ -	c = styler.SafeGetCharAt(pos, '\0'); -	if (c == 'u' || c == 'i') { -		pos++; -		c = styler.SafeGetCharAt(pos, '\0'); -		n = styler.SafeGetCharAt(pos + 1, '\0'); -		if (c == '8') { -			pos++; -		} else if (c == '1' && n == '6') { -			pos += 2; -		} else if (c == '3' && n == '2') { -			pos += 2; -		} else if (c == '6' && n == '4') { -			pos += 2; -		} else if (styler.Match(pos, "size")) { -			pos += 4; -		} else { -			error = true; -		} -	/* See if it's a floating point literal. These literals have to be base 10. -	 */ -	} else if (!error) { -		/* If there's a period, it's a floating point literal unless it's -		 * followed by an identifier (meaning this is a method call, e.g. -		 * `1.foo()`) or another period, in which case it's a range (e.g. 1..2) -		 */ -		n = styler.SafeGetCharAt(pos + 1, '\0'); -		if (c == '.' && !(IsIdentifierStart(n) || n == '.')) { -			error |= base != 10; -			pos++; -			/* It's ok to have no digits after the period. */ -			ScanDigits(styler, pos, 10); -		} - -		/* Look for the exponentiation. */ -		c = styler.SafeGetCharAt(pos, '\0'); -		if (c == 'e' || c == 'E') { -			error |= base != 10; -			pos++; -			c = styler.SafeGetCharAt(pos, '\0'); -			if (c == '-' || c == '+') -				pos++; -			/* It is invalid to have no digits in the exponent. */ -			error |= !ScanDigits(styler, pos, 10); -		} - -		/* Scan the floating point suffix. */ -		c = styler.SafeGetCharAt(pos, '\0'); -		if (c == 'f') { -			error |= base != 10; -			pos++; -			c = styler.SafeGetCharAt(pos, '\0'); -			n = styler.SafeGetCharAt(pos + 1, '\0'); -			if (c == '3' && n == '2') { -				pos += 2; -			} else if (c == '6' && n == '4') { -				pos += 2; -			} else { -				error = true; -			} -		} -	} - -	if (error) -		styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); -	else -		styler.ColourTo(pos - 1, SCE_RUST_NUMBER); -} - -static bool IsOneCharOperator(int c) { -	return c == ';' || c == ',' || c == '(' || c == ')' -	    || c == '{' || c == '}' || c == '[' || c == ']' -	    || c == '@' || c == '#' || c == '~' || c == '+' -	    || c == '*' || c == '/' || c == '^' || c == '%' -	    || c == '.' || c == ':' || c == '!' || c == '<' -	    || c == '>' || c == '=' || c == '-' || c == '&' -	    || c == '|' || c == '$' || c == '?'; -} - -static bool IsTwoCharOperator(int c, int n) { -	return (c == '.' && n == '.') || (c == ':' && n == ':') -	    || (c == '!' && n == '=') || (c == '<' && n == '<') -	    || (c == '<' && n == '=') || (c == '>' && n == '>') -	    || (c == '>' && n == '=') || (c == '=' && n == '=') -	    || (c == '=' && n == '>') || (c == '-' && n == '>') -	    || (c == '&' && n == '&') || (c == '|' && n == '|') -	    || (c == '-' && n == '=') || (c == '&' && n == '=') -	    || (c == '|' && n == '=') || (c == '+' && n == '=') -	    || (c == '*' && n == '=') || (c == '/' && n == '=') -	    || (c == '^' && n == '=') || (c == '%' && n == '='); -} - -static bool IsThreeCharOperator(int c, int n, int n2) { -	return (c == '<' && n == '<' && n2 == '=') -	    || (c == '>' && n == '>' && n2 == '='); -} - -static bool IsValidCharacterEscape(int c) { -	return c == 'n'  || c == 'r' || c == 't' || c == '\\' -	    || c == '\'' || c == '"' || c == '0'; -} - -static bool IsValidStringEscape(int c) { -	return IsValidCharacterEscape(c) || c == '\n' || c == '\r'; -} - -static bool ScanNumericEscape(Accessor &styler, Sci_Position& pos, Sci_Position num_digits, bool stop_asap) { -	for (;;) { -		int c = styler.SafeGetCharAt(pos, '\0'); -		if (!IsADigit(c, 16)) -			break; -		num_digits--; -		pos++; -		if (num_digits == 0 && stop_asap) -			return true; -	} -	if (num_digits == 0) { -		return true; -	} else { -		return false; -	} -} - -/* This is overly permissive for character literals in order to accept UTF-8 encoded - * character literals. */ -static void ScanCharacterLiteralOrLifetime(Accessor &styler, Sci_Position& pos, bool ascii_only) { -	pos++; -	int c = styler.SafeGetCharAt(pos, '\0'); -	int n = styler.SafeGetCharAt(pos + 1, '\0'); -	bool done = false; -	bool valid_lifetime = !ascii_only && IsIdentifierStart(c); -	bool valid_char = true; -	bool first = true; -	while (!done) { -		switch (c) { -			case '\\': -				done = true; -				if (IsValidCharacterEscape(n)) { -					pos += 2; -				} else if (n == 'x') { -					pos += 2; -					valid_char = ScanNumericEscape(styler, pos, 2, false); -				} else if (n == 'u' && !ascii_only) { -					pos += 2; -					if (styler.SafeGetCharAt(pos, '\0') != '{') { -						// old-style -						valid_char = ScanNumericEscape(styler, pos, 4, false); -					} else { -						int n_digits = 0; -						while (IsADigit(styler.SafeGetCharAt(++pos, '\0'), 16) && n_digits++ < 6) { -						} -						if (n_digits > 0 && styler.SafeGetCharAt(pos, '\0') == '}') -							pos++; -						else -							valid_char = false; -					} -				} else if (n == 'U' && !ascii_only) { -					pos += 2; -					valid_char = ScanNumericEscape(styler, pos, 8, false); -				} else { -					valid_char = false; -				} -				break; -			case '\'': -				valid_char = !first; -				done = true; -				break; -			case '\t': -			case '\n': -			case '\r': -			case '\0': -				valid_char = false; -				done = true; -				break; -			default: -				if (ascii_only && !IsASCII((char)c)) { -					done = true; -					valid_char = false; -				} else if (!IsIdentifierContinue(c) && !first) { -					done = true; -				} else { -					pos++; -				} -				break; -		} -		c = styler.SafeGetCharAt(pos, '\0'); -		n = styler.SafeGetCharAt(pos + 1, '\0'); - -		first = false; -	} -	if (styler.SafeGetCharAt(pos, '\0') == '\'') { -		valid_lifetime = false; -	} else { -		valid_char = false; -	} -	if (valid_lifetime) { -		styler.ColourTo(pos - 1, SCE_RUST_LIFETIME); -	} else if (valid_char) { -		pos++; -		styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTECHARACTER : SCE_RUST_CHARACTER); -	} else { -		styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); -	} -} - -enum CommentState { -	UnknownComment, -	DocComment, -	NotDocComment -}; - -/* - * The rule for block-doc comments is as follows: /xxN and /x! (where x is an asterisk, N is a non-asterisk) start doc comments. - * Otherwise it's a regular comment. - */ -static void ResumeBlockComment(Accessor &styler, Sci_Position& pos, Sci_Position max, CommentState state, int level) { -	int c = styler.SafeGetCharAt(pos, '\0'); -	bool maybe_doc_comment = false; -	if (c == '*') { -		int n = styler.SafeGetCharAt(pos + 1, '\0'); -		if (n != '*' && n != '/') { -			maybe_doc_comment = true; -		} -	} else if (c == '!') { -		maybe_doc_comment = true; -	} - -	for (;;) { -		int n = styler.SafeGetCharAt(pos + 1, '\0'); -		if (pos == styler.LineEnd(styler.GetLine(pos))) -			styler.SetLineState(styler.GetLine(pos), level); -		if (c == '*') { -			pos++; -			if (n == '/') { -				pos++; -				level--; -				if (level == 0) { -					styler.SetLineState(styler.GetLine(pos), 0); -					if (state == DocComment || (state == UnknownComment && maybe_doc_comment)) -						styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCKDOC); -					else -						styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCK); -					break; -				} -			} -		} else if (c == '/') { -			pos++; -			if (n == '*') { -				pos++; -				level++; -			} -		} -		else { -			pos++; -		} -		if (pos >= max) { -			if (state == DocComment || (state == UnknownComment && maybe_doc_comment)) -				styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCKDOC); -			else -				styler.ColourTo(pos - 1, SCE_RUST_COMMENTBLOCK); -			break; -		} -		c = styler.SafeGetCharAt(pos, '\0'); -	} -} - -/* - * The rule for line-doc comments is as follows... ///N and //! (where N is a non slash) start doc comments. - * Otherwise it's a normal line comment. - */ -static void ResumeLineComment(Accessor &styler, Sci_Position& pos, Sci_Position max, CommentState state) { -	bool maybe_doc_comment = false; -	int c = styler.SafeGetCharAt(pos, '\0'); -	if (c == '/') { -		if (pos < max) { -			pos++; -			c = styler.SafeGetCharAt(pos, '\0'); -			if (c != '/') { -				maybe_doc_comment = true; -			} -		} -	} else if (c == '!') { -		maybe_doc_comment = true; -	} - -	while (pos < max && c != '\n') { -		if (pos == styler.LineEnd(styler.GetLine(pos))) -			styler.SetLineState(styler.GetLine(pos), 0); -		pos++; -		c = styler.SafeGetCharAt(pos, '\0'); -	} - -	if (state == DocComment || (state == UnknownComment && maybe_doc_comment)) -		styler.ColourTo(pos - 1, SCE_RUST_COMMENTLINEDOC); -	else -		styler.ColourTo(pos - 1, SCE_RUST_COMMENTLINE); -} - -static void ScanComments(Accessor &styler, Sci_Position& pos, Sci_Position max) { -	pos++; -	int c = styler.SafeGetCharAt(pos, '\0'); -	pos++; -	if (c == '/') -		ResumeLineComment(styler, pos, max, UnknownComment); -	else if (c == '*') -		ResumeBlockComment(styler, pos, max, UnknownComment, 1); -} - -static void ResumeString(Accessor &styler, Sci_Position& pos, Sci_Position max, bool ascii_only) { -	int c = styler.SafeGetCharAt(pos, '\0'); -	bool error = false; -	while (c != '"' && !error) { -		if (pos >= max) { -			error = true; -			break; -		} -		if (pos == styler.LineEnd(styler.GetLine(pos))) -			styler.SetLineState(styler.GetLine(pos), 0); -		if (c == '\\') { -			int n = styler.SafeGetCharAt(pos + 1, '\0'); -			if (IsValidStringEscape(n)) { -				pos += 2; -			} else if (n == 'x') { -				pos += 2; -				error = !ScanNumericEscape(styler, pos, 2, true); -			} else if (n == 'u' && !ascii_only) { -				pos += 2; -				if (styler.SafeGetCharAt(pos, '\0') != '{') { -					// old-style -					error = !ScanNumericEscape(styler, pos, 4, true); -				} else { -					int n_digits = 0; -					while (IsADigit(styler.SafeGetCharAt(++pos, '\0'), 16) && n_digits++ < 6) { -					} -					if (n_digits > 0 && styler.SafeGetCharAt(pos, '\0') == '}') -						pos++; -					else -						error = true; -				} -			} else if (n == 'U' && !ascii_only) { -				pos += 2; -				error = !ScanNumericEscape(styler, pos, 8, true); -			} else { -				pos += 1; -				error = true; -			} -		} else { -			if (ascii_only && !IsASCII((char)c)) -				error = true; -			else -				pos++; -		} -		c = styler.SafeGetCharAt(pos, '\0'); -	} -	if (!error) -		pos++; -	styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTESTRING : SCE_RUST_STRING); -} - -static void ResumeRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, int num_hashes, bool ascii_only) { -	for (;;) { -		if (pos == styler.LineEnd(styler.GetLine(pos))) -			styler.SetLineState(styler.GetLine(pos), num_hashes); - -		int c = styler.SafeGetCharAt(pos, '\0'); -		if (c == '"') { -			pos++; -			int trailing_num_hashes = 0; -			while (styler.SafeGetCharAt(pos, '\0') == '#' && trailing_num_hashes < num_hashes) { -				trailing_num_hashes++; -				pos++; -			} -			if (trailing_num_hashes == num_hashes) { -				styler.SetLineState(styler.GetLine(pos), 0); -				break; -			} -		} else if (pos >= max) { -			break; -		} else { -			if (ascii_only && !IsASCII((char)c)) -				break; -			pos++; -		} -	} -	styler.ColourTo(pos - 1, ascii_only ? SCE_RUST_BYTESTRINGR : SCE_RUST_STRINGR); -} - -static void ScanRawString(Accessor &styler, Sci_Position& pos, Sci_Position max, bool ascii_only) { -	pos++; -	int num_hashes = 0; -	while (styler.SafeGetCharAt(pos, '\0') == '#') { -		num_hashes++; -		pos++; -	} -	if (styler.SafeGetCharAt(pos, '\0') != '"') { -		styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); -	} else { -		pos++; -		ResumeRawString(styler, pos, max, num_hashes, ascii_only); -	} -} - -void SCI_METHOD LexerRust::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { -	PropSetSimple props; -	Accessor styler(pAccess, &props); -	Sci_Position pos = startPos; -	Sci_Position max = pos + length; - -	styler.StartAt(pos); -	styler.StartSegment(pos); - -	if (initStyle == SCE_RUST_COMMENTBLOCK || initStyle == SCE_RUST_COMMENTBLOCKDOC) { -		ResumeBlockComment(styler, pos, max, initStyle == SCE_RUST_COMMENTBLOCKDOC ? DocComment : NotDocComment, styler.GetLineState(styler.GetLine(pos) - 1)); -	} else if (initStyle == SCE_RUST_COMMENTLINE || initStyle == SCE_RUST_COMMENTLINEDOC) { -		ResumeLineComment(styler, pos, max, initStyle == SCE_RUST_COMMENTLINEDOC ? DocComment : NotDocComment); -	} else if (initStyle == SCE_RUST_STRING) { -		ResumeString(styler, pos, max, false); -	} else if (initStyle == SCE_RUST_BYTESTRING) { -		ResumeString(styler, pos, max, true); -	} else if (initStyle == SCE_RUST_STRINGR) { -		ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), false); -	} else if (initStyle == SCE_RUST_BYTESTRINGR) { -		ResumeRawString(styler, pos, max, styler.GetLineState(styler.GetLine(pos) - 1), true); -	} - -	while (pos < max) { -		int c = styler.SafeGetCharAt(pos, '\0'); -		int n = styler.SafeGetCharAt(pos + 1, '\0'); -		int n2 = styler.SafeGetCharAt(pos + 2, '\0'); - -		if (pos == 0 && c == '#' && n == '!' && n2 != '[') { -			pos += 2; -			ResumeLineComment(styler, pos, max, NotDocComment); -		} else if (IsWhitespace(c)) { -			ScanWhitespace(styler, pos, max); -		} else if (c == '/' && (n == '/' || n == '*')) { -			ScanComments(styler, pos, max); -		} else if (c == 'r' && (n == '#' || n == '"')) { -			ScanRawString(styler, pos, max, false); -		} else if (c == 'b' && n == 'r' && (n2 == '#' || n2 == '"')) { -			pos++; -			ScanRawString(styler, pos, max, true); -		} else if (c == 'b' && n == '"') { -			pos += 2; -			ResumeString(styler, pos, max, true); -		} else if (c == 'b' && n == '\'') { -			pos++; -			ScanCharacterLiteralOrLifetime(styler, pos, true); -		} else if (IsIdentifierStart(c)) { -			ScanIdentifier(styler, pos, keywords); -		} else if (IsADigit(c)) { -			ScanNumber(styler, pos); -		} else if (IsThreeCharOperator(c, n, n2)) { -			pos += 3; -			styler.ColourTo(pos - 1, SCE_RUST_OPERATOR); -		} else if (IsTwoCharOperator(c, n)) { -			pos += 2; -			styler.ColourTo(pos - 1, SCE_RUST_OPERATOR); -		} else if (IsOneCharOperator(c)) { -			pos++; -			styler.ColourTo(pos - 1, SCE_RUST_OPERATOR); -		} else if (c == '\'') { -			ScanCharacterLiteralOrLifetime(styler, pos, false); -		} else if (c == '"') { -			pos++; -			ResumeString(styler, pos, max, false); -		} else { -			pos++; -			styler.ColourTo(pos - 1, SCE_RUST_LEXERROR); -		} -	} -	styler.ColourTo(pos - 1, SCE_RUST_DEFAULT); -	styler.Flush(); -} - -void SCI_METHOD LexerRust::Fold(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) { - -	if (!options.fold) -		return; - -	LexAccessor styler(pAccess); - -	Sci_PositionU endPos = startPos + length; -	int visibleChars = 0; -	bool inLineComment = false; -	Sci_Position lineCurrent = styler.GetLine(startPos); -	int levelCurrent = SC_FOLDLEVELBASE; -	if (lineCurrent > 0) -		levelCurrent = styler.LevelAt(lineCurrent-1) >> 16; -	Sci_PositionU lineStartNext = styler.LineStart(lineCurrent+1); -	int levelMinCurrent = levelCurrent; -	int levelNext = levelCurrent; -	char chNext = styler[startPos]; -	int styleNext = styler.StyleAt(startPos); -	int style = initStyle; -	const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty(); -	for (Sci_PositionU i = startPos; i < endPos; i++) { -		char ch = chNext; -		chNext = styler.SafeGetCharAt(i + 1); -		int stylePrev = style; -		style = styleNext; -		styleNext = styler.StyleAt(i + 1); -		bool atEOL = i == (lineStartNext-1); -		if ((style == SCE_RUST_COMMENTLINE) || (style == SCE_RUST_COMMENTLINEDOC)) -			inLineComment = true; -		if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) && !inLineComment) { -			if (!IsStreamCommentStyle(stylePrev)) { -				levelNext++; -			} else if (!IsStreamCommentStyle(styleNext) && !atEOL) { -				// Comments don't end at end of line and the next character may be unstyled. -				levelNext--; -			} -		} -		if (options.foldComment && options.foldCommentExplicit && ((style == SCE_RUST_COMMENTLINE) || options.foldExplicitAnywhere)) { -			if (userDefinedFoldMarkers) { -				if (styler.Match(i, options.foldExplicitStart.c_str())) { -					levelNext++; -				} else if (styler.Match(i, options.foldExplicitEnd.c_str())) { -					levelNext--; -				} -			} else { -				if ((ch == '/') && (chNext == '/')) { -					char chNext2 = styler.SafeGetCharAt(i + 2); -					if (chNext2 == '{') { -						levelNext++; -					} else if (chNext2 == '}') { -						levelNext--; -					} -				} -			} -		} -		if (options.foldSyntaxBased && (style == SCE_RUST_OPERATOR)) { -			if (ch == '{') { -				// Measure the minimum before a '{' to allow -				// folding on "} else {" -				if (levelMinCurrent > levelNext) { -					levelMinCurrent = levelNext; -				} -				levelNext++; -			} else if (ch == '}') { -				levelNext--; -			} -		} -		if (!IsASpace(ch)) -			visibleChars++; -		if (atEOL || (i == endPos-1)) { -			int levelUse = levelCurrent; -			if (options.foldSyntaxBased && options.foldAtElse) { -				levelUse = levelMinCurrent; -			} -			int lev = levelUse | levelNext << 16; -			if (visibleChars == 0 && options.foldCompact) -				lev |= SC_FOLDLEVELWHITEFLAG; -			if (levelUse < levelNext) -				lev |= SC_FOLDLEVELHEADERFLAG; -			if (lev != styler.LevelAt(lineCurrent)) { -				styler.SetLevel(lineCurrent, lev); -			} -			lineCurrent++; -			lineStartNext = styler.LineStart(lineCurrent+1); -			levelCurrent = levelNext; -			levelMinCurrent = levelCurrent; -			if (atEOL && (i == static_cast<Sci_PositionU>(styler.Length()-1))) { -				// There is an empty line at end of file so give it same level and empty -				styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG); -			} -			visibleChars = 0; -			inLineComment = false; -		} -	} -} - -LexerModule lmRust(SCLEX_RUST, LexerRust::LexerFactoryRust, "rust", rustWordLists); | 
