// 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 'forwarding_listener.dart' show ForwardingListener;

class ClassHeaderRecoveryListener extends ForwardingListener {
  Token extendsKeyword;
  Token implementsKeyword;
  Token withKeyword;

  void clear() {
    extendsKeyword = null;
    implementsKeyword = null;
    withKeyword = null;
  }

  @override
  void handleClassExtends(Token extendsKeyword, int typeCount) {
    this.extendsKeyword = extendsKeyword;
    super.handleClassExtends(extendsKeyword, typeCount);
  }

  @override
  void handleClassOrMixinImplements(
      Token implementsKeyword, int interfacesCount) {
    this.implementsKeyword = implementsKeyword;
    super.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
  }

  @override
  void handleClassWithClause(Token withKeyword) {
    this.withKeyword = withKeyword;
    super.handleClassWithClause(withKeyword);
  }
}

class ImportRecoveryListener extends ForwardingListener {
  Token asKeyword;
  Token deferredKeyword;
  Token ifKeyword;
  bool hasCombinator = false;

  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);
  }
}

class MixinHeaderRecoveryListener extends ForwardingListener {
  Token onKeyword;
  Token implementsKeyword;

  void clear() {
    onKeyword = null;
    implementsKeyword = null;
  }

  @override
  void handleClassOrMixinImplements(
      Token implementsKeyword, int interfacesCount) {
    this.implementsKeyword = implementsKeyword;
    super.handleClassOrMixinImplements(implementsKeyword, interfacesCount);
  }

  @override
  void handleMixinOn(Token onKeyword, int typeCount) {
    this.onKeyword = onKeyword;
    super.handleMixinOn(onKeyword, typeCount);
  }
}
