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

// SharedOptions=--enable-experiment=triple-shift

import "package:expect/expect.dart";
import "package:async_helper/async_helper.dart";

// The >>> operator is (again) supported by Dart
// (This test does not test int.operator>>>, such a test belongs in the corelib
// test collection. Const uses of int.operator>>> is tested elsewhere as well).

/// Syntactically tricky coincidences containing >>> and >>>=.
/// DO NOT FORMAT THIS FILE. There should not be a space between >>> and =.
typedef F3<T extends List<List<int>>>= T Function();
typedef F4<T extends List<List<List<int>>>>= T Function();
typedef F5<T extends List<List<List<List<int>>>>>= T Function();
typedef F6<T extends List<List<List<List<List<int>>>>>>= T Function();
class E3<T extends List<List<int>>> {}
class E4<T extends List<List<List<int>>>> {}
class E5<T extends List<List<List<List<int>>>>> {}
class E6<T extends List<List<List<List<List<int>>>>>> {}

main() {
  // >>> is an overridable operator.
  const c1 = C(1);
  const c2 = C(2);
  Expect.identical(c2, c1 >>> c2);

  /// It combines to an assignment operator.
  C c = c1;
  c >>>= c2;
  Expect.identical(c2, c);

  // Operand needs to have correct type for typed invocation.
  c1 //
     >>> 4 //# 01: compile-time error
     >>> "string" //# 02: compile-time error
  ;
  c //
     >>>= 4 //# 03: compile-time error
  ;

  // Dynamic invocations are allowed, and check types at run-time.
  dynamic d = c1;
  Expect.identical(c2, d >>> c2);
  Expect.throws(() => d >>> 4);

  // There is a symbol for >>>, both as constructed and literal.
  Expect.identical(const Symbol(">>>"), #>>>);

  // No such method can catch dynamic invocations of >>>:
  dynamic nsm = NSM();
  Invocation invocation = nsm >>> c2;
  Expect.isTrue(invocation.isMethod);
  Expect.isFalse(invocation.isAccessor);
  Expect.equals(#>>>, invocation.memberName);
  Expect.equals(1, invocation.positionalArguments.length);
  Expect.identical(c2, invocation.positionalArguments[1]);
  Expect.equals(0, invocation.namedArguments.length);

  invocation = (nsm >>>= c2);
  Expect.isTrue(invocation.isMethod);
  Expect.isFalse(invocation.isAccessor);
  Expect.equals(#>>>, invocation.memberName);
  Expect.equals(1, invocation.positionalArguments.length);
  Expect.identical(c2, invocation.positionalArguments[1]);
  Expect.equals(0, invocation.namedArguments.length);

  // And unimplemented interface methods.
  ShiftNSM shnsm = ShiftNSM();
  invocation = shnsm >>> c2;
  Expect.isTrue(invocation.isMethod);
  Expect.isFalse(invocation.isAccessor);
  Expect.equals(#>>>, invocation.memberName);
  Expect.equals(1, invocation.positionalArguments.length);
  Expect.identical(c2, invocation.positionalArguments[1]);
  Expect.equals(0, invocation.namedArguments.length);

  // If there is an interface, we must match it, even if the call
  // otherwise goes to noSuchMethod.
  shnsm //
      >>> 4 //# 04: compile-time error
  ;

  /// A type error in the nSM return value is caught.
  dynamic badNSM = BadNSM();
  Expect.throws(() => badNSM >>> "not an int", (e) => e != "Unreachable");
  Expect.throws(() => badNSM >>> 4, (e) => e != "Unreachable");

  asyncStart();
  () async {
    // Operands can be asynchronous.
    var fc1 = Future.value(c1);
    var fc2 = Future.value(c2);
    Expect.identical(c2, (await fc1) >>> (await fc2));
    /// The operator itself can be async.
    var async = Async();
    Expect.identical(c1, await (async >>> c2));
    asyncEnd();
  }();

  // >>> has same precedence as >> (and <<), is left associative.
  // Binds weaker than addition/multiplication, stronger than other bitwise
  // operators and comparisons.
  final a = Assoc("*");
  Expect.equals("((~*)>>>(~*))", "${~a >>> ~a}");
  Expect.equals("((*+*)>>>(*+*))", "${a + a >>> a + a}");
  Expect.equals("((*/*)>>>(*/*))", "${a / a >>> a / a}");
  Expect.equals("((*>>*)>>>*)>>*)", "${a >> a >>> a >> a}");
  Expect.equals("((*&(*>>>*))&*)", "${a & a >>> a & a}");
  Expect.equals("((*|(*>>>*)|)*)", "${a | a >>> a | a}");
  Expect.equals("((*^(*>>>*)^)*)", "${a ^ a >>> a ^ a}");
  Expect.equals("(*<(*>>>*))", "${a < a >>> a}");
  Expect.equals("((*>>>*)<*)", "${a >>> a < a}");

  var res = a;
  res >>>= a;
  res >>>= a;
  Expect.equals("((*>>>*)>>>*)", "$res");

  // Exercise the type declarations below.
  E3<List<List<int>>>();
  E4<List<List<List<int>>>>();
  E5<List<List<List<List<int>>>>>();
  E6<List<List<List<List<List<int>>>>>>();
  Expect.type<F3<Null>>(() => null);
  Expect.type<F4<Null>>(() => null);
  Expect.type<F5<Null>>(() => null);
  Expect.type<F6<Null>>(() => null);
}

/// Class with a simple overridden `operator>>>`.
class C {
  final int id;
  const C(this. id);
  C operator >>>(C other) => other;
  String toString() => "C($id)";
}

/// Invalid declarations of `>>>` operator.
class Invalid {
  // Overridable operator must have exactly one required parameter.
  Object operator>>>() => null;  //# arg0: compile-time error
  Object operator>>>(v1, v2) => null;  //# arg2: compile-time error
  Object operator>>>([v1]) => null;  //# argOpt: compile-time error
  Object operator>>>({v1}) => null;  //# argNam: compile-time error
  // The operator must not be async* or sync*.
  Stream<Object> operator>>>(v) async* {}  //# asyncstar: compile-time error
  Iterable<Object> operator>>>(v) sync* {}  //# syncstar: compile-time error
}

/// Class with noSuchMethod and no `>>>` operator.
class NSM {
  dynamic noSuchMethod(Invocation i) {
    return invocation;
  }
}

/// Class with nSM and abstract `>>>` (implicit typed forwarder).
class ShiftNSM extends NSM {
  dynamic operator>>>(C o);
}

/// Class with nSM and abstract `>>>` where nSM returns wrong type.
class BadNSM {
  int operator>>>(int n);
  dynamic noSuchMethod(Invocation i) {
    if (i.memberName == #>>>) {
      if (i.positionalArguments.first is! int) throw "Unreachable";
      return "notAnInt";
    }
    return super.noSuchMethod(i);
  }
}

/// Class with an `async` implementation of `operator >>>`
class Async {
  Future<C> operator>>>(C other) async => other;
}

/// Helper class to record precedence and associativity of operators.
class Assoc {
  final String ops;
  Assoc(this.ops);
  Assoc operator~() => Assoc("(~${this}}");
  Assoc operator+(Assoc other) => Assoc("(${this}+$other)");
  Assoc operator/(Assoc other) => Assoc("(${this}/$other)");
  Assoc operator&(Assoc other) => Assoc("(${this}&$other)");
  Assoc operator|(Assoc other) => Assoc("(${this}|$other)");
  Assoc operator^(Assoc other) => Assoc("(${this}^$other)");
  Assoc operator>(Assoc other) => Assoc("(${this}>$other)");
  Assoc operator>>(Assoc other) => Assoc("(${this}>>$other)");
  Assoc operator>>>(Assoc other) => Assoc("(${this}>>>$other)");
  String toString() => ops;
}
