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

// Tests that field promotion distinguishes `this` accesses from `super`
// accesses when they resolve to different fields.

// In this test, the fields in question have generic types. This is an important
// special case to test because the analyzer uses special "Member" data
// structures to track accesses to fields with generic types.

// Since the analyzer has different logic for resolving ordinary variable gets
// and variable gets that look like member invocations, both scenarios are
// tested.

import '../static_type_helper.dart';

class Base<T extends Object> {
  final T? _t;
  final T? Function() _f;
  Base(this._t, this._f);
}

/// In this class, `_t` and `_f` override the declarations of `_t` and `_f` in
/// `super`, so their promotions should be tracked separately.
class DerivedClassThatOverridesBaseMembers<T extends Object> extends Base<T> {
  final T? _t;
  final T? Function() _f;
  DerivedClassThatOverridesBaseMembers(
      this._t, this._f, T? superI, T? Function() superF)
      : super(superI, superF);

  void ordinaryVariableGet() {
    _t.expectStaticType<Exactly<T?>>();
    this._t.expectStaticType<Exactly<T?>>();
    super._t.expectStaticType<Exactly<T?>>();
    if (_t != null) {
      _t.expectStaticType<Exactly<T>>();
      this._t.expectStaticType<Exactly<T>>();
      super._t.expectStaticType<Exactly<T?>>();
    }
    if (this._t != null) {
      _t.expectStaticType<Exactly<T>>();
      this._t.expectStaticType<Exactly<T>>();
      super._t.expectStaticType<Exactly<T?>>();
    }
    if (super._t != null) {
      _t.expectStaticType<Exactly<T?>>();
      this._t.expectStaticType<Exactly<T?>>();
      super._t.expectStaticType<Exactly<T>>();
    }
  }

  void invokedVariableGet() {
    _f().expectStaticType<Exactly<T?>>();
    this._f().expectStaticType<Exactly<T?>>();
    super._f().expectStaticType<Exactly<T?>>();
    if (_f is T Function()) {
      _f().expectStaticType<Exactly<T>>();
      this._f().expectStaticType<Exactly<T>>();
      super._f().expectStaticType<Exactly<T?>>();
    }
    if (this._f is T Function()) {
      _f().expectStaticType<Exactly<T>>();
      this._f().expectStaticType<Exactly<T>>();
      super._f().expectStaticType<Exactly<T?>>();
    }
    if (super._f is T Function()) {
      _f().expectStaticType<Exactly<T?>>();
      this._f().expectStaticType<Exactly<T?>>();
      super._f().expectStaticType<Exactly<T>>();
    }
  }
}

/// In this class, `_i` and `_f` refer to the declarations of `_i` and `_f` in
/// `super`. However, accesses made through `this` still promote independently
/// from accesses made through `super`, since this is simpler to implement, has
/// no soundness problems, and is unlikely to cause problems in real-world code.
class DerivedClassThatOverridesNothing<T extends Object> extends Base<T> {
  DerivedClassThatOverridesNothing(super._t, super.f);

  void ordinaryVariableGet() {
    _t.expectStaticType<Exactly<T?>>();
    this._t.expectStaticType<Exactly<T?>>();
    super._t.expectStaticType<Exactly<T?>>();
    if (_t != null) {
      _t.expectStaticType<Exactly<T>>();
      this._t.expectStaticType<Exactly<T>>();
      super._t.expectStaticType<Exactly<T?>>();
    }
    if (this._t != null) {
      _t.expectStaticType<Exactly<T>>();
      this._t.expectStaticType<Exactly<T>>();
      super._t.expectStaticType<Exactly<T?>>();
    }
    if (super._t != null) {
      _t.expectStaticType<Exactly<T?>>();
      this._t.expectStaticType<Exactly<T?>>();
      super._t.expectStaticType<Exactly<T>>();
    }
  }

  void invokedVariableGet() {
    _f().expectStaticType<Exactly<T?>>();
    this._f().expectStaticType<Exactly<T?>>();
    super._f().expectStaticType<Exactly<T?>>();
    if (_f is T Function()) {
      _f().expectStaticType<Exactly<T>>();
      this._f().expectStaticType<Exactly<T>>();
      super._f().expectStaticType<Exactly<T?>>();
    }
    if (this._f is T Function()) {
      _f().expectStaticType<Exactly<T>>();
      this._f().expectStaticType<Exactly<T>>();
      super._f().expectStaticType<Exactly<T?>>();
    }
    if (super._f is T Function()) {
      _f().expectStaticType<Exactly<T?>>();
      this._f().expectStaticType<Exactly<T?>>();
      super._f().expectStaticType<Exactly<T>>();
    }
  }
}

main() {
  int f() => 0;
  int? g() => null;
  DerivedClassThatOverridesBaseMembers<int>(0, f, null, g)
    ..ordinaryVariableGet()
    ..invokedVariableGet();
  DerivedClassThatOverridesBaseMembers<int>(null, g, 0, f)
    ..ordinaryVariableGet()
    ..invokedVariableGet();
  DerivedClassThatOverridesNothing<int>(0, f)
    ..ordinaryVariableGet()
    ..invokedVariableGet();
}
