// 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 works with null-aware cascades whose targets are
// non-nullable (that is, the cascades are "unnecessarily" null-aware).
//
// Since the cascades are unnecessarily null-aware, the analyzer produces
// warnings for it, so this test has to have "error" expectations.

import '../static_type_helper.dart';

class C {
  final Object? _field;
  C([this._field]);
  void f([_]) {}
}

void cascadedAccessReceivesTheBenefitOfPromotion(C c) {
  // If a field of an object is promoted prior to its use in a cascade, accesses
  // to the field within cascade sections retain the promotion.
  c._field as int;
  c._field.expectStaticType<Exactly<int>>();
  c
    ?.._field.expectStaticType<Exactly<int>>()
//  ^^^
// [analyzer] STATIC_WARNING.INVALID_NULL_AWARE_OPERATOR
    .._field.expectStaticType<Exactly<int>>();

  // And the promotion remains on later accesses to the same variable.
  c._field.expectStaticType<Exactly<int>>();
}

void fieldAccessOnACascadeExpressionRetainsPromotion(C c) {
  // If a field of an object is promoted prior to its use in a cascade, accesses
  // to the field from outside the cascade retain the promotion.
  c._field as int;
  c._field.expectStaticType<Exactly<int>>();
  (c?..f())._field.expectStaticType<Exactly<int>>();
//  ^^^
// [analyzer] STATIC_WARNING.INVALID_NULL_AWARE_OPERATOR

  // And the promotion remains on later accesses to the same variable.
  c._field.expectStaticType<Exactly<int>>();
}

void fieldsPromotableWithinCascade(C c) {
  // Within a cascade, a field can be promoted using `!`.
  c
    ?.._field.expectStaticType<Exactly<Object?>>()
//  ^^^
// [analyzer] STATIC_WARNING.INVALID_NULL_AWARE_OPERATOR
    .._field!.expectStaticType<Exactly<Object>>()
    .._field.expectStaticType<Exactly<Object>>();

  // After the cascade, the promotion is not retained, because of the implicit
  // control flow join implied by the `?..`. (In principle it would be sound to
  // preserve the promotion, but it's extra work to do so, and it's not clear
  // that there would be enough user benefit to justify the work).
  c?._field.expectStaticType<Exactly<Object?>>();
// ^^
// [analyzer] STATIC_WARNING.INVALID_NULL_AWARE_OPERATOR
}

void ephemeralValueFieldsArePromotable(C Function() getC) {
  // Fields of an ephemeral value (one that is not explicitly stored in a
  // variable) can still be promoted in one cascade section, and the results of
  // the promotion can be seen in later cascade sections.
  getC()
    ?.._field.expectStaticType<Exactly<Object?>>()
//  ^^^
// [analyzer] STATIC_WARNING.INVALID_NULL_AWARE_OPERATOR
    .._field!.expectStaticType<Exactly<Object>>()
    .._field.expectStaticType<Exactly<Object>>();

  // But they won't be seen if a fresh value is created.
  getC()._field.expectStaticType<Exactly<Object?>>();
}

void writeCapturedValueFieldsArePromotable(C c) {
  // Fields of a write-captured variable can still be promoted in one cascade
  // section, and the results of the promotion can be seen in later cascade
  // sections. This is because the target of the cascade is stored in an
  // implicit temporary variable, separate from the write-captured variable.
  f() {
    c = C(null);
  }

  c
    ?.._field.expectStaticType<Exactly<Object?>>()
//  ^^^
// [analyzer] STATIC_WARNING.INVALID_NULL_AWARE_OPERATOR
    .._field!.expectStaticType<Exactly<Object>>()
    .._field.expectStaticType<Exactly<Object>>();

  // But fields of the write-captured variable itself aren't promoted.
  c._field.expectStaticType<Exactly<Object?>>();
}

void writeDefeatsLaterAccessesButNotCascadeTarget(C c) {
  // If a write to a variable happens during a cascade, any promotions based on
  // that variable are invalidated, but the target of the cascade remains
  // promoted, since it's stored in an implicit temporarly variable that's
  // unaffected by the write.
  c._field as C;
  c._field.expectStaticType<Exactly<C>>();
  c
    ?.._field.f([c = C(C()), c._field.expectStaticType<Exactly<Object?>>()])
//  ^^^
// [analyzer] STATIC_WARNING.INVALID_NULL_AWARE_OPERATOR
    .._field.expectStaticType<Exactly<C>>();
  c._field.expectStaticType<Exactly<Object?>>();
}

void cascadedInvocationsPermitted(C c) {
  // A promoted field may be invoked inside a cascade.
  c._field as int Function();
  c._field.expectStaticType<Exactly<int Function()>>();
  c?.._field().expectStaticType<Exactly<int>>();
}

main() {
  cascadedAccessReceivesTheBenefitOfPromotion(C(0));
  fieldAccessOnACascadeExpressionRetainsPromotion(C(0));
  fieldsPromotableWithinCascade(C(0));
  ephemeralValueFieldsArePromotable(() => C(0));
  writeCapturedValueFieldsArePromotable(C(0));
  writeDefeatsLaterAccessesButNotCascadeTarget(C(C()));
  int f() => 0;
  cascadedInvocationsPermitted(C(f));
}
