// 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.md file.

// @dart = 2.9

library fasta.test.incremental_dynamic_test;

import "package:_fe_analyzer_shared/src/messages/diagnostic_message.dart"
    show
        DiagnosticMessage,
        DiagnosticMessageHandler,
        getMessageCodeObject,
        getMessageArguments;

import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;

import 'package:async_helper/async_helper.dart' show asyncTest;

import 'package:expect/expect.dart' show Expect;

import 'package:kernel/target/targets.dart' show NoneTarget, TargetFlags;

import "package:front_end/src/api_prototype/compiler_options.dart"
    show CompilerOptions;

import 'package:front_end/src/testing/compiler_common.dart' show compileScript;

import 'package:front_end/src/fasta/fasta_codes.dart'
    show codeSuperclassHasNoMethod;

/// A subclass of NoneTarget that enables Flutter style super-mixin semantics.
///
/// See dartbug.com/31542 for details of the semantics.
class NoneTargetWithSuperMixins extends NoneTarget {
  NoneTargetWithSuperMixins(TargetFlags flags) : super(flags);

  @override
  bool get enableSuperMixins => true;
}

const String testSource = '''
abstract class A {
  void foo(String value);
}

abstract class B {
  void bar(String value);
}

abstract class Mixin extends A with B {
  void bar(String value) {
    // CFE should report an error on the line below under the normal
    // Dart 2 semantics, because super invocation targets abstract
    // member. However when enableSuperMixins is set
    // in the Target the error should be suppressed.
    super.bar(value);
    // This line should always trigger an error, irrespective of
    // whether super-mixins semantics is enabled or disabled.
    super.baz();
  }
}

class NotMixin extends A with B {
  void bar(String value) {
    // Both of these should be reported as error independently
    // of super-mixins semantics because NotMixin is not an abstract
    // class.
    super.foo(value);
    super.quux();
  }

  void foo(String value) {}
}

void main() {
  // Dummy main to avoid warning.
}
''';

DiagnosticMessageHandler _makeDiagnosticMessageHandler(Set<String> names) {
  return (DiagnosticMessage message) {
    Expect.equals(Severity.error, message.severity);
    Expect.identical(codeSuperclassHasNoMethod, getMessageCodeObject(message));
    Expect.isTrue(message.plainTextFormatted.length == 1);
    names.add(getMessageArguments(message)['name']);
  };
}

/// Check that by default an error is reported for all unresolved super
/// invocations: independently of weather they target abstract super members
/// or nonexistent targets.
Future<void> testDisabledSuperMixins() async {
  var missingSuperMethodNames = new Set<String>();
  var options = new CompilerOptions()
    ..onDiagnostic = _makeDiagnosticMessageHandler(missingSuperMethodNames);
  await compileScript(testSource, options: options);
  Expect.setEquals(
      const <String>['bar', 'baz', 'foo', 'quux'], missingSuperMethodNames);
}

/// Check that in an abstract class an error is reported only for a
/// super-invocation that targets an non-existent method, a super-invocation
/// that targets an abstract member of the super-class should not be reported.
/// In non-abstract class we should report both cases as an error.
Future<void> testEnabledSuperMixins() async {
  var missingSuperMethodNames = new Set<String>();
  var options = new CompilerOptions()
    ..onDiagnostic = _makeDiagnosticMessageHandler(missingSuperMethodNames)
    ..target = new NoneTargetWithSuperMixins(new TargetFlags());
  await compileScript(testSource, options: options);
  Expect.setEquals(
      const <String>['baz', 'foo', 'quux'], missingSuperMethodNames);
}

void main() {
  asyncTest(() async {
    await testDisabledSuperMixins();
    await testEnabledSuperMixins();
  });
}
