blob: 4b15b5fb4b64ee7ea293d6c7842e4386b75aac7a [file] [log] [blame]
// Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
library dart2js.scanner.string_scanner;
import 'token.dart' show Token, SyntheticStringToken, TokenType;
import 'token.dart' as analyzer show StringToken;
import 'abstract_scanner.dart'
show AbstractScanner, LanguageVersionChanged, ScannerConfiguration;
import 'token_impl.dart'
show CommentToken, DartDocToken, LanguageVersionToken, StringToken;
import 'error_token.dart' show ErrorToken;
/**
* Scanner that reads from a String and creates tokens that points to
* substrings.
*/
class StringScanner extends AbstractScanner {
/** The file content. */
late String string;
/** The current offset in [string]. */
late int scanOffset = -1;
StringScanner(String string,
{ScannerConfiguration? configuration,
bool includeComments: false,
LanguageVersionChanged? languageVersionChanged})
: string = ensureZeroTermination(string),
super(configuration, includeComments, languageVersionChanged);
StringScanner.recoveryOptionScanner(StringScanner copyFrom)
: super.recoveryOptionScanner(copyFrom) {
string = copyFrom.string;
scanOffset = copyFrom.scanOffset;
}
StringScanner createRecoveryOptionScanner() {
return new StringScanner.recoveryOptionScanner(this);
}
static String ensureZeroTermination(String string) {
return (string.isEmpty || string.codeUnitAt(string.length - 1) != 0)
// TODO(lry): abort instead of copying the array, or warn?
? string + '\x00'
: string;
}
static bool isLegalIdentifier(String identifier) {
StringScanner scanner = new StringScanner(identifier);
Token startToken = scanner.tokenize();
return startToken is! ErrorToken && startToken.next!.isEof;
}
int advance() => string.codeUnitAt(++scanOffset);
int peek() => string.codeUnitAt(scanOffset + 1);
int get stringOffset => scanOffset;
int currentAsUnicode(int next) => next;
void handleUnicode(int startScanOffset) {}
@override
analyzer.StringToken createSubstringToken(
TokenType type, int start, bool asciiOnly,
[int extraOffset = 0]) {
return new StringToken.fromSubstring(
type, string, start, scanOffset + extraOffset, tokenStart,
canonicalize: true, precedingComments: comments);
}
@override
analyzer.StringToken createSyntheticSubstringToken(
TokenType type, int start, bool asciiOnly, String syntheticChars) {
String source = string.substring(start, scanOffset);
return new SyntheticStringToken(
type, source + syntheticChars, tokenStart, source.length);
}
@override
CommentToken createCommentToken(TokenType type, int start, bool asciiOnly,
[int extraOffset = 0]) {
return new CommentToken.fromSubstring(
type, string, start, scanOffset + extraOffset, tokenStart,
canonicalize: true);
}
@override
DartDocToken createDartDocToken(TokenType type, int start, bool asciiOnly,
[int extraOffset = 0]) {
return new DartDocToken.fromSubstring(
type, string, start, scanOffset + extraOffset, tokenStart,
canonicalize: true);
}
@override
LanguageVersionToken createLanguageVersionToken(
int start, int major, int minor) {
return new LanguageVersionToken.fromSubstring(
string, start, scanOffset, tokenStart, major, minor,
canonicalize: true);
}
bool atEndOfFile() => scanOffset >= string.length - 1;
}