blob: 61668898d9493fab624daacbf48b9a308592a46f [file] [log] [blame]
// Copyright (c) 2017, 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.
import '../../scanner/token.dart' show Token;
import '../messages.dart' show Message;
import 'forwarding_listener.dart' show ForwardingListener;
import 'listener.dart' show Listener;
/// The abstract superclass of recovery listeners.
///
/// During the first phase of recovery, some portion of the code is reparsed
/// to record information (e.g. tokens) that were not recorded during
/// the primary parse phase. During this phase, the [listener] is null
/// so that reparsing will not effect the primary listener state,
/// but the [_primaryListener] is non-null for those few events
/// where the parser requires the listener to interpret the token stream.
class RecoveryListener extends ForwardingListener {
// TODO(danrubel): remove the need for this field and this class
// by removing listener events that interpret the token stream for the parser.
final Listener _primaryListener;
RecoveryListener(this._primaryListener);
@override
Token handleUnrecoverableError(Token token, Message message) =>
_primaryListener.handleUnrecoverableError(token, message);
@override
Token newSyntheticToken(Token next) =>
_primaryListener.newSyntheticToken(next);
}
class ClassHeaderRecoveryListener extends RecoveryListener {
Token extendsKeyword;
Token implementsKeyword;
Token withKeyword;
ClassHeaderRecoveryListener(Listener primaryListener)
: super(primaryListener);
void clear() {
extendsKeyword = null;
implementsKeyword = null;
withKeyword = null;
}
@override
void endMixinApplication(Token withKeyword) {
this.withKeyword = withKeyword;
super.endMixinApplication(withKeyword);
}
@override
void handleClassExtends(Token extendsKeyword) {
this.extendsKeyword = extendsKeyword;
super.handleClassExtends(extendsKeyword);
}
@override
void handleClassImplements(Token implementsKeyword, int interfacesCount) {
this.implementsKeyword = implementsKeyword;
super.handleClassImplements(implementsKeyword, interfacesCount);
}
}
class ImportRecoveryListener extends RecoveryListener {
Token asKeyword;
Token deferredKeyword;
Token ifKeyword;
bool hasCombinator = false;
ImportRecoveryListener(Listener primaryListener) : super(primaryListener);
void clear() {
asKeyword = null;
deferredKeyword = null;
ifKeyword = null;
hasCombinator = false;
}
void endConditionalUri(Token ifKeyword, Token leftParen, Token equalSign) {
this.ifKeyword = ifKeyword;
super.endConditionalUri(ifKeyword, leftParen, equalSign);
}
void endHide(Token hideKeyword) {
this.hasCombinator = true;
super.endHide(hideKeyword);
}
void endShow(Token showKeyword) {
this.hasCombinator = true;
super.endShow(showKeyword);
}
void handleImportPrefix(Token deferredKeyword, Token asKeyword) {
this.deferredKeyword = deferredKeyword;
this.asKeyword = asKeyword;
super.handleImportPrefix(deferredKeyword, asKeyword);
}
}