// Copyright (c) 2015, 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.

// @dart = 2.10

import '../common.dart';
import '../common/elements.dart' show CommonElements;
import '../common/names.dart' show Identifiers, Selectors;
import '../elements/entities.dart';
import '../inferrer/types.dart';
import '../kernel/no_such_method_resolver.dart';
import '../serialization/serialization.dart';

/// [NoSuchMethodRegistry] and [NoSuchMethodData] categorizes `noSuchMethod`
/// implementations.
///
/// If user code includes `noSuchMethod` implementations, type inference is
/// hindered because (for instance) any selector where the type of the
/// receiver is not known all implementations of `noSuchMethod` must be taken
/// into account when inferring the return type.
///
/// The situation can be ameliorated with some heuristics for disregarding some
/// `noSuchMethod` implementations during type inference. We can partition
/// `noSuchMethod` implementations into 4 categories.
///
/// Implementations in category A are the default implementations
/// `Object.noSuchMethod` and `Interceptor.noSuchMethod`.
///
/// Implementations in category B syntactically immediately throw, for example:
///
///     noSuchMethod(x) => throw 'not implemented'
///
/// Implementations in category C are not applicable, for example:
///
///     noSuchMethod() { /* missing parameter */ }
///     noSuchMethod(a, b) { /* too many parameters */ }
///
/// Implementations that do not fall into category A, B or C are in category D.
/// They are the only category of implementation that are considered during type
/// inference.
///
/// Implementations that syntactically just forward to the super implementation,
/// for example:
///
///     noSuchMethod(x) => super.noSuchMethod(x);
///
/// are in the same category as the superclass implementation. This covers a
/// common case, where users implement `noSuchMethod` with these dummy
/// implementations to avoid warnings.

/// Registry for collecting `noSuchMethod` implementations and categorizing them
/// into categories `A`, `B`, `C`, `D`.
class NoSuchMethodRegistry {
  /// The implementations that fall into category A, described above.
  final Set<FunctionEntity> _defaultImpls = {};

  /// The implementations that fall into category B, described above.
  final Set<FunctionEntity> _throwingImpls = {};

  /// The implementations that fall into category C, described above.
  // TODO(johnniwinther): Remove this category when Dart 1 is no longer
  // supported.
  final Set<FunctionEntity> _notApplicableImpls = {};

  /// The implementations that fall into category D, described above.
  final Set<FunctionEntity> _otherImpls = {};

  /// The implementations that have not yet been categorized.
  final Set<FunctionEntity> _uncategorizedImpls = {};

  /// The implementations that a forwarding syntax as defined by
  /// [NoSuchMethodResolver.hasForwardSyntax].
  final Set<FunctionEntity> _forwardingSyntaxImpls = {};

  final CommonElements _commonElements;
  final NoSuchMethodResolver _resolver;

  NoSuchMethodRegistry(this._commonElements, this._resolver);

  NoSuchMethodResolver get internalResolverForTesting => _resolver;

  /// `true` if a category `B` method has been seen so far.
  bool get hasThrowingNoSuchMethod => _throwingImpls.isNotEmpty;

  /// `true` if a category `D` method has been seen so far.
  bool get hasComplexNoSuchMethod => _otherImpls.isNotEmpty;

  Iterable<FunctionEntity> get defaultImpls => _defaultImpls;

  Iterable<FunctionEntity> get throwingImpls => _throwingImpls;

  Iterable<FunctionEntity> get otherImpls => _otherImpls;

  /// Register [noSuchMethodElement].
  void registerNoSuchMethod(FunctionEntity noSuchMethodElement) {
    _uncategorizedImpls.add(noSuchMethodElement);
  }

  /// Categorizes the registered methods.
  void onQueueEmpty() {
    _uncategorizedImpls.forEach(_categorizeImpl);
    _uncategorizedImpls.clear();
  }

  NsmCategory _categorizeImpl(FunctionEntity element) {
    assert(element.name == Identifiers.noSuchMethod_);
    assert(!element.isAbstract);
    if (_defaultImpls.contains(element)) {
      return NsmCategory.DEFAULT;
    }
    if (_throwingImpls.contains(element)) {
      return NsmCategory.THROWING;
    }
    if (_otherImpls.contains(element)) {
      return NsmCategory.OTHER;
    }
    if (_notApplicableImpls.contains(element)) {
      return NsmCategory.NOT_APPLICABLE;
    }
    if (!Selectors.noSuchMethod_.signatureApplies(element)) {
      _notApplicableImpls.add(element);
      return NsmCategory.NOT_APPLICABLE;
    }
    if (_commonElements.isDefaultNoSuchMethodImplementation(element)) {
      _defaultImpls.add(element);
      return NsmCategory.DEFAULT;
    } else if (_resolver.hasForwardingSyntax(element)) {
      _forwardingSyntaxImpls.add(element);
      // If the implementation is 'noSuchMethod(x) => super.noSuchMethod(x);'
      // then it is in the same category as the super call.
      FunctionEntity superCall = _resolver.getSuperNoSuchMethod(element);
      NsmCategory category = _categorizeImpl(superCall);
      switch (category) {
        case NsmCategory.DEFAULT:
          _defaultImpls.add(element);
          break;
        case NsmCategory.THROWING:
          _throwingImpls.add(element);
          break;
        case NsmCategory.OTHER:
          _otherImpls.add(element);
          break;
        case NsmCategory.NOT_APPLICABLE:
          // If the super method is not applicable, the call is redirected to
          // `Object.noSuchMethod`.
          _defaultImpls.add(element);
          category = NsmCategory.DEFAULT;
          break;
      }
      return category;
    } else if (_resolver.hasThrowingSyntax(element)) {
      _throwingImpls.add(element);
      return NsmCategory.THROWING;
    } else {
      _otherImpls.add(element);
      return NsmCategory.OTHER;
    }
  }

  /// Closes the registry and returns data object used during type inference.
  NoSuchMethodData close() {
    return NoSuchMethodData(
        _throwingImpls, _otherImpls, _forwardingSyntaxImpls);
  }
}

/// Data object used during type inference.
///
/// Post inference collected category `D` methods are into subcategories `D1`
/// and `D2`.
class NoSuchMethodData {
  /// Tag used for identifying serialized [NoSuchMethodData] objects in a
  /// debugging data stream.
  static const String tag = 'no-such-method-data';

  /// The implementations that fall into category B, described above.
  final Set<FunctionEntity> _throwingImpls;

  /// The implementations that fall into category D, described above.
  final Set<FunctionEntity> _otherImpls;

  /// The implementations that fall into category D1
  final Set<FunctionEntity> _complexNoReturnImpls = {};

  /// The implementations that fall into category D2
  final Set<FunctionEntity> _complexReturningImpls = {};

  final Set<FunctionEntity> _forwardingSyntaxImpls;

  NoSuchMethodData(
      this._throwingImpls, this._otherImpls, this._forwardingSyntaxImpls);

  /// Deserializes a [NoSuchMethodData] object from [source].
  factory NoSuchMethodData.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    Set<FunctionEntity> throwingImpls =
        source.readMembers<FunctionEntity>().toSet();
    Set<FunctionEntity> otherImpls =
        source.readMembers<FunctionEntity>().toSet();
    Set<FunctionEntity> forwardingSyntaxImpls =
        source.readMembers<FunctionEntity>().toSet();
    List<FunctionEntity> complexNoReturnImpls =
        source.readMembers<FunctionEntity>();
    List<FunctionEntity> complexReturningImpls =
        source.readMembers<FunctionEntity>();
    source.end(tag);
    return NoSuchMethodData(throwingImpls, otherImpls, forwardingSyntaxImpls)
      .._complexNoReturnImpls.addAll(complexNoReturnImpls)
      .._complexReturningImpls.addAll(complexReturningImpls);
  }

  /// Serializes this [NoSuchMethodData] to [sink].
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMembers(_throwingImpls);
    sink.writeMembers(_otherImpls);
    sink.writeMembers(_forwardingSyntaxImpls);
    sink.writeMembers(_complexNoReturnImpls);
    sink.writeMembers(_complexReturningImpls);
    sink.end(tag);
  }

  Iterable<FunctionEntity> get throwingImpls => _throwingImpls;

  Iterable<FunctionEntity> get otherImpls => _otherImpls;

  Iterable<FunctionEntity> get forwardingSyntaxImpls => _forwardingSyntaxImpls;

  Iterable<FunctionEntity> get complexNoReturnImpls => _complexNoReturnImpls;

  Iterable<FunctionEntity> get complexReturningImpls => _complexReturningImpls;

  /// Now that type inference is complete, split category D into two
  /// subcategories: D1, those that have no return type, and D2, those
  /// that have a return type.
  void categorizeComplexImplementations(GlobalTypeInferenceResults results) {
    _otherImpls.forEach((FunctionEntity element) {
      if (results.resultOfMember(element).throwsAlways) {
        _complexNoReturnImpls.add(element);
      } else {
        _complexReturningImpls.add(element);
      }
    });
  }

  /// Emits a diagnostic about methods in categories `B`, `D1` and `D2`.
  void emitDiagnostic(DiagnosticReporter reporter) {
    _throwingImpls.forEach((e) {
      if (!_forwardingSyntaxImpls.contains(e)) {
        reporter.reportHintMessage(e, MessageKind.DIRECTLY_THROWING_NSM);
      }
    });
    _complexNoReturnImpls.forEach((e) {
      if (!_forwardingSyntaxImpls.contains(e)) {
        reporter.reportHintMessage(e, MessageKind.COMPLEX_THROWING_NSM);
      }
    });
    _complexReturningImpls.forEach((e) {
      if (!_forwardingSyntaxImpls.contains(e)) {
        reporter.reportHintMessage(e, MessageKind.COMPLEX_RETURNING_NSM);
      }
    });
  }

  /// Returns [true] if the given element is a complex [noSuchMethod]
  /// implementation. An implementation is complex if it falls into
  /// category D, as described above.
  bool isComplex(FunctionEntity element) {
    assert(element.name == Identifiers.noSuchMethod_);
    return _otherImpls.contains(element);
  }
}

enum NsmCategory {
  DEFAULT,
  THROWING,
  NOT_APPLICABLE,
  OTHER,
}
