blob: 52f438869b7179a7b498b57fb5cee91efefe729c [file] [log] [blame]
// Copyright (c) 2016, 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 fasta.analyzer.token_utils;
import 'package:front_end/src/scanner/token.dart' show CommentToken, Token;
import 'package:front_end/src/fasta/scanner/token_constants.dart';
import 'package:front_end/src/scanner/errors.dart' show translateErrorToken;
import 'package:front_end/src/scanner/errors.dart' as analyzer
show ScannerErrorCode;
/// Class capable of converting a stream of Fasta tokens to a stream of analyzer
/// tokens.
///
/// This is a class rather than an ordinary method so that it can be subclassed
/// in tests.
class ToAnalyzerTokenStreamConverter {
/// Converts a stream of Fasta tokens (starting with [token] and continuing to
/// EOF) to a stream of analyzer tokens. This modifies the fasta token stream
/// to be an analyzer token stream by removing error tokens and reporting
/// those errors to the associated error listener.
Token convertTokens(Token firstToken) {
Token token = new Token.eof(-1)..setNext(firstToken);
Token next = firstToken;
while (!next.isEof) {
if (next.type.kind == BAD_INPUT_TOKEN) {
translateErrorToken(next, reportError);
token.setNext(next.next);
} else {
token = next;
}
next = token.next;
}
return firstToken;
}
/// Handles an error found during [convertTokens].
///
/// Intended to be overridden by derived classes; by default, does nothing.
void reportError(analyzer.ScannerErrorCode errorCode, int offset,
List<Object> arguments) {}
}
/// Search for the token before [target] starting the search with [start].
/// Return `null` if [target] is a comment token
/// or the previous token cannot be found.
Token findPrevious(Token start, Token target) {
if (start == target || target is CommentToken) {
return null;
}
Token token = start is CommentToken ? start.parent : start;
do {
Token next = token.next;
if (next == target) {
return token;
}
token = next;
} while (!token.isEof);
return null;
}