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

// Verify semantics of the ??= operator, including order of operations, by
// keeping track of the operations performed.

import "package:expect/expect.dart";
import "assignment_helper.dart" as h;

bad() {
  Expect.fail('Should not be executed');
}

var xGetValue = null;

get x {
  h.operations.add('x');
  var tmp = xGetValue;
  xGetValue = null;
  return tmp;
}

void set x(value) {
  h.operations.add('x=$value');
}

var yGetValue = null;

get y {
  h.operations.add('y');
  var tmp = yGetValue;
  yGetValue = null;
  return tmp;
}

void set y(value) {
  h.operations.add('y=$value');
}

var zGetValue = null;

get z {
  h.operations.add('z');
  var tmp = zGetValue;
  zGetValue = null;
  return tmp;
}

void set z(value) {
  h.operations.add('z=$value');
}

var fValue = null;

f() {
  h.operations.add('f()');
  var tmp = fValue;
  fValue = null;
  return tmp;
}

void check(expectedValue, f(), expectedOperations) {
  Expect.equals(expectedValue, f());
  Expect.listEquals(expectedOperations, h.operations);
  h.operations = [];
}

class C {
  final String s;

  C(this.s);

  @override
  String toString() => s;

  static var xGetValue = null;

  static get x {
    h.operations.add('C.x');
    var tmp = xGetValue;
    xGetValue = null;
    return tmp;
  }

  static void set x(value) {
    h.operations.add('C.x=$value');
  }

  var vGetValue = null;

  get v {
    h.operations.add('$s.v');
    var tmp = vGetValue;
    vGetValue = null;
    return tmp;
  }

  void set v(value) {
    h.operations.add('$s.v=$value');
  }

  var indexGetValue = null;

  operator [](index) {
    h.operations.add('$s[$index]');
    var tmp = indexGetValue;
    indexGetValue = null;
    return tmp;
  }

  void operator []=(index, value) {
    h.operations.add('$s[$index]=$value');
  }

  final finalOne = 1;
  final finalNull = null;

  void instanceTest() {
    // v ??= e is equivalent to ((x) => x == null ? v = e : x)(v)
    vGetValue = 1; check(1, () => v ??= bad(), ['$s.v']);
    yGetValue = 1; check(1, () => v ??= y, ['$s.v', 'y', '$s.v=1']);
    finalOne ??= null;
//  ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL
// [cfe] The setter 'finalOne' isn't defined for the class 'C'.
//               ^^^^
// [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
    yGetValue = 1;
  }
}

class D extends C {
  D(String s) : super(s);

  get v => bad();

  void set v(value) {
    bad();
  }

  void derivedInstanceTest() {
    // super.v ??= e is equivalent to
    // ((x) => x == null ? super.v = e : x)(super.v)
    vGetValue = 1; check(1, () => super.v ??= bad(), ['$s.v']);
    yGetValue = 1; check(1, () => super.v ??= y, ['$s.v', 'y', '$s.v=1']);
  }
}

main() {
  // Make sure the "none" test fails if "??=" is not implemented.  This makes
  // status files easier to maintain.
  var _;
  _ ??= null;

  new C('c').instanceTest();
  new D('d').derivedInstanceTest();

  // v ??= e is equivalent to ((x) => x == null ? v = e : x)(v)
  xGetValue = 1; check(1, () => x ??= bad(), ['x']);
  yGetValue = 1; check(1, () => x ??= y, ['x', 'y', 'x=1']);
  h.xGetValue = 1; check(1, () => h.x ??= bad(), ['h.x']);
  yGetValue = 1; check(1, () => h.x ??= y, ['h.x', 'y', 'h.x=1']);
  { var l = 1; check(1, () => l ??= bad(), []); }
  //                                ^^^^^
  // [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
  { var l; yGetValue = 1; check(1, () => l ??= y, ['y']); Expect.equals(1, l); }
  { final l = 1; l ??= null; }
  //             ^
  // [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_FINAL_LOCAL
  // [cfe] Can't assign to the final variable 'l'.
  //                   ^^^^
  // [analyzer] COMPILE_TIME_ERROR.INVALID_ASSIGNMENT
  //                   ^^^^
  // [analyzer] STATIC_WARNING.DEAD_NULL_AWARE_EXPRESSION
  C ??= null;
//^
// [analyzer] COMPILE_TIME_ERROR.ASSIGNMENT_TO_TYPE
// [cfe] Can't assign to a type literal.
  h ??= null;
//^
// [analyzer] COMPILE_TIME_ERROR.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT
// [cfe] A prefix can't be used as an expression.
  h[0] ??= null;
//^
// [analyzer] COMPILE_TIME_ERROR.PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT
// [cfe] A prefix can't be used as an expression.

  // C.v ??= e is equivalent to ((x) => x == null ? C.v = e : x)(C.v)
  C.xGetValue = 1; check(1, () => C.x ??= bad(), ['C.x']);
  yGetValue = 1; check(1, () => C.x ??= y, ['C.x', 'y', 'C.x=1']);
  h.C.xGetValue = 1; check(1, () => h.C.x ??= bad(), ['h.C.x']);
  yGetValue = 1; check(1, () => h.C.x ??= y, ['h.C.x', 'y', 'h.C.x=1']);

  // e1.v ??= e2 is equivalent to
  // ((x) => ((y) => y == null ? x.v = e2 : y)(x.v))(e1)
  xGetValue = new C('x'); xGetValue.vGetValue = 1;
  check(1, () => x.v ??= bad(), ['x', 'x.v']);
  xGetValue = new C('x'); yGetValue = 1;
  check(1, () => x.v ??= y, ['x', 'x.v', 'y', 'x.v=1']);
  fValue = new C('f()'); fValue.vGetValue = 1;
  check(1, () => f().v ??= bad(), ['f()', 'f().v']);
  fValue = new C('f()'); yGetValue = 1;
  check(1, () => f().v ??= y, ['f()', 'f().v', 'y', 'f().v=1']);

  // e1[e2] ??= e3 is equivalent to
  // ((a, i) => ((x) => x == null ? a[i] = e3 : x)(a[i]))(e1, e2)
  xGetValue = new C('x'); yGetValue = 1; xGetValue.indexGetValue = 2;
  check(2, () => x[y] ??= bad(), ['x', 'y', 'x[1]']);
  xGetValue = new C('x'); yGetValue = 1; zGetValue = 2;
  check(2, () => x[y] ??= z, ['x', 'y', 'x[1]', 'z', 'x[1]=2']);

  // e1?.v ??= e2 is equivalent to ((x) => x == null ? null : x.v ??= e2)(e1).
  check(null, () => x?.v ??= bad(), ['x']);
  xGetValue = new C('x'); xGetValue.vGetValue = 1;
  check(1, () => x?.v ??= bad(), ['x', 'x.v']);
  xGetValue = new C('x'); yGetValue = 1;
  check(1, () => x?.v ??= y, ['x', 'x.v', 'y', 'x.v=1']);

  // C?.v ??= e2 is equivalent to C.v ??= e2.
  C.xGetValue = 1;
  check(1, () => C?.x ??= bad(), ['C.x']);
  h.C.xgetValue = 1;
  //  ^^^^^^^^^
  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_SETTER
  // [cfe] Setter not found: 'xgetValue'.
  check(1, () => h.c?.x ??= bad(), ['h.C.x']);
  //               ^
  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_PREFIXED_NAME
  // [cfe] Getter not found: 'c'.
  yGetValue = 1;
  check(1, () => C?.x ??= y, ['C.x', 'y', 'C.x=1']);
  yGetValue = 1;
  check(1, () => h.C?.x ??= y, ['h.C.x', 'y', 'h.C.x=1']);
}
