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

import 'package:expect/expect.dart';
import 'package:js/js.dart';

const dart2js = const bool.fromEnvironment('dart.library._dart2js_only');
const ddc = const bool.fromEnvironment('dart.library._ddc_only');

dynamic obj;

@JS()
external dynamic eval(String code);

@JS()
@pragma('dart2js:never-inline')
external String returnsNull();

@JS()
@pragma('dart2js:prefer-inline')
external String returnsNullInlined();

@JS()
@pragma('dart2js:never-inline')
external String returnsUndefined();

@JS()
@pragma('dart2js:prefer-inline')
external String returnsUndefinedInlined();

@JS()
@pragma('dart2js:never-inline')
external int get getsNull;

@JS()
@pragma('dart2js:prefer-inline')
external int get getsNullInlined;

@JS()
@pragma('dart2js:never-inline')
external int get undefinedGetter;

@JS()
@pragma('dart2js:prefer-inline')
external int get undefinedGetterInlined;

@JS()
@pragma('dart2js:never-inline')
external double Function() get getterFunctionReturnsNull;

@JS()
@pragma('dart2js:prefer-inline')
external double Function() get getterFunctionReturnsNullInlined;

@JS()
@pragma('dart2js:never-inline')
external double Function() get getterFunctionReturnsUndefined;

@JS()
@pragma('dart2js:prefer-inline')
external double Function() get getterFunctionReturnsUndefinedInlined;

@JS()
@pragma('dart2js:never-inline')
external bool nullField;

@JS()
@pragma('dart2js:prefer-inline')
external bool nullFieldInlined;

@JS()
@pragma('dart2js:never-inline')
external bool undefinedField;

@JS()
@pragma('dart2js:prefer-inline')
external bool undefinedFieldInlined;

@JS()
@pragma('dart2js:never-inline')
external int? nullableFunction();

@JS()
@pragma('dart2js:prefer-inline')
external int? nullableFunctionInlined();

@JS()
@pragma('dart2js:never-inline')
external int? get nullableGetter;

@JS()
@pragma('dart2js:prefer-inline')
external int? get nullableGetterInlined;

@JS()
@pragma('dart2js:never-inline')
external int? nullableField;

@JS()
@pragma('dart2js:prefer-inline')
external int? nullableFieldInlined;

@JS()
@anonymous
class SomeClass {
  @pragma('dart2js:never-inline')
  external String returnsNull();

  @pragma('dart2js:prefer-inline')
  external String returnsNullInlined();

  @pragma('dart2js:never-inline')
  external String returnsUndefined();

  @pragma('dart2js:prefer-inline')
  external String returnsUndefinedInlined();

  @pragma('dart2js:never-inline')
  external int get getsNull;

  @pragma('dart2js:prefer-inline')
  external int get getsNullInlined;

  @pragma('dart2js:never-inline')
  external int get undefinedGetter;

  @pragma('dart2js:prefer-inline')
  external int get undefinedGetterInlined;

  @pragma('dart2js:never-inline')
  external double Function() get getterFunctionReturnsNull;

  @pragma('dart2js:prefer-inline')
  external double Function() get getterFunctionReturnsNullInlined;

  @pragma('dart2js:never-inline')
  external double Function() get getterFunctionReturnsUndefined;

  @pragma('dart2js:prefer-inline')
  external double Function() get getterFunctionReturnsUndefinedInlined;

  @pragma('dart2js:never-inline')
  external bool nullField;

  @pragma('dart2js:prefer-inline')
  external bool nullFieldInlined;

  @pragma('dart2js:never-inline')
  external bool undefinedField;

  @pragma('dart2js:prefer-inline')
  external bool undefinedFieldInlined;

  @pragma('dart2js:never-inline')
  external int? nullableFunction();

  @pragma('dart2js:prefer-inline')
  external int? nullableFunctionInlined();

  @pragma('dart2js:never-inline')
  external int? get nullableGetter;

  @pragma('dart2js:prefer-inline')
  external int? get nullableGetterInlined;

  @pragma('dart2js:never-inline')
  external int? nullableField;

  @pragma('dart2js:prefer-inline')
  external int? nullableFieldInlined;
}

@JS()
@anonymous
class AnotherClass {
  @pragma('dart2js:never-inline')
  external static String staticReturnsNull();

  @pragma('dart2js:prefer-inline')
  external static String staticReturnsNullInlined();

  @pragma('dart2js:never-inline')
  external static String staticReturnsUndefined();

  @pragma('dart2js:prefer-inline')
  external static String staticReturnsUndefinedInlined();

  @pragma('dart2js:never-inline')
  external static int get staticGetsNull;

  @pragma('dart2js:prefer-inline')
  external static int get staticGetsNullInlined;

  @pragma('dart2js:never-inline')
  external static int get staticUndefinedGetter;

  @pragma('dart2js:prefer-inline')
  external static int get staticUndefinedGetterInlined;

  @pragma('dart2js:never-inline')
  external static double Function() get staticGetterFunctionReturnsNull;

  @pragma('dart2js:prefer-inline')
  external static double Function() get staticGetterFunctionReturnsNullInlined;

  @pragma('dart2js:never-inline')
  external static double Function() get staticGetterFunctionReturnsUndefined;

  @pragma('dart2js:prefer-inline')
  external static double Function()
  get staticGetterFunctionReturnsUndefinedInlined;

  @pragma('dart2js:never-inline')
  external static bool staticNullField;

  @pragma('dart2js:prefer-inline')
  external static bool staticNullFieldInlined;

  @pragma('dart2js:never-inline')
  external static bool staticUndefinedField;

  @pragma('dart2js:prefer-inline')
  external static bool staticUndefinedFieldInlined;

  @pragma('dart2js:never-inline')
  external static int? staticNullableFunction();

  @pragma('dart2js:prefer-inline')
  external static int? staticNullableFunctionInlined();

  @pragma('dart2js:never-inline')
  external static int? get staticNullableGetter;

  @pragma('dart2js:prefer-inline')
  external static int? get staticNullableGetterInlined;

  @pragma('dart2js:never-inline')
  external static int? staticNullableField;

  @pragma('dart2js:prefer-inline')
  external static int? staticNullableFieldInlined;
}

@JS()
class NamedClass {
  @pragma('dart2js:never-inline')
  external String returnsNull();

  @pragma('dart2js:prefer-inline')
  external String returnsNullInlined();

  @pragma('dart2js:never-inline')
  external String returnsUndefined();

  @pragma('dart2js:prefer-inline')
  external String returnsUndefinedInlined();

  @pragma('dart2js:never-inline')
  external static String staticReturnsNull();

  @pragma('dart2js:prefer-inline')
  external static String staticReturnsNullInlined();

  @pragma('dart2js:never-inline')
  external static String staticReturnsUndefined();

  @pragma('dart2js:prefer-inline')
  external static String staticReturnsUndefinedInlined();

  @pragma('dart2js:never-inline')
  external int get getsNull;

  @pragma('dart2js:prefer-inline')
  external int get getsNullInlined;

  @pragma('dart2js:never-inline')
  external int get undefinedGetter;

  @pragma('dart2js:prefer-inline')
  external int get undefinedGetterInlined;

  @pragma('dart2js:never-inline')
  external static int get staticGetsNull;

  @pragma('dart2js:prefer-inline')
  external static int get staticGetsNullInlined;

  @pragma('dart2js:never-inline')
  external static int get staticUndefinedGetter;

  @pragma('dart2js:prefer-inline')
  external static int get staticUndefinedGetterInlined;

  @pragma('dart2js:never-inline')
  external double Function() get getterFunctionReturnsNull;

  @pragma('dart2js:prefer-inline')
  external double Function() get getterFunctionReturnsNullInlined;

  @pragma('dart2js:never-inline')
  external double Function() get getterFunctionReturnsUndefined;

  @pragma('dart2js:prefer-inline')
  external double Function() get getterFunctionReturnsUndefinedInlined;

  @pragma('dart2js:never-inline')
  external static double Function() get staticGetterFunctionReturnsNull;

  @pragma('dart2js:prefer-inline')
  external static double Function() get staticGetterFunctionReturnsNullInlined;

  @pragma('dart2js:never-inline')
  external static double Function() get staticGetterFunctionReturnsUndefined;

  @pragma('dart2js:prefer-inline')
  external static double Function()
  get staticGetterFunctionReturnsUndefinedInlined;

  @pragma('dart2js:never-inline')
  external bool nullField;

  @pragma('dart2js:prefer-inline')
  external bool nullFieldInlined;

  @pragma('dart2js:never-inline')
  external bool undefinedField;

  @pragma('dart2js:prefer-inline')
  external bool undefinedFieldInlined;

  @pragma('dart2js:never-inline')
  external int? nullableFunction();

  @pragma('dart2js:prefer-inline')
  external int? nullableFunctionInlined();

  @pragma('dart2js:never-inline')
  external int? get nullableGetter;

  @pragma('dart2js:prefer-inline')
  external int? get nullableGetterInlined;

  @pragma('dart2js:never-inline')
  external int? nullableField;

  @pragma('dart2js:prefer-inline')
  external int? nullableFieldInlined;

  @pragma('dart2js:never-inline')
  external static bool staticNullField;

  @pragma('dart2js:prefer-inline')
  external static bool staticNullFieldInlined;

  @pragma('dart2js:never-inline')
  external static bool staticUndefinedField;

  @pragma('dart2js:prefer-inline')
  external static bool staticUndefinedFieldInlined;

  @pragma('dart2js:never-inline')
  external static int? staticNullableFunction();

  @pragma('dart2js:prefer-inline')
  external static int? staticNullableFunctionInlined();

  @pragma('dart2js:never-inline')
  external static int? get staticNullableGetter;

  @pragma('dart2js:prefer-inline')
  external static int? get staticNullableGetterInlined;

  @pragma('dart2js:never-inline')
  external static int? staticNullableField;

  @pragma('dart2js:prefer-inline')
  external static int? staticNullableFieldInlined;

  external factory NamedClass.createNamedClass();
}

@JS()
external SomeClass createSomeClass();

void topLevelMemberTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  eval(r'self.returnsNull = function() { return null; }');
  Expect.throwsTypeErrorWhen(checksEnabled, () => returnsNull());

  eval(r'self.returnsUndefined = function() { return void 0; }');
  Expect.throwsTypeErrorWhen(checksEnabled, () => returnsUndefined());

  var functionTearoff = returnsNull;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  functionTearoff = returnsUndefined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());

  eval(r'self.getsNull = null;');
  Expect.throwsTypeErrorWhen(checksEnabled, () => getsNull);
  Expect.throwsTypeErrorWhen(checksEnabled, () => undefinedGetter);

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  eval(r'self.getterFunctionReturnsNull = function() { return null; };');
  Expect.isNull(getterFunctionReturnsNull());
  var getterFunction = getterFunctionReturnsNull;
  Expect.isNull(getterFunction());

  eval(
    r'self.getterFunctionReturnsUndefined = function() { '
    'return void 0; };',
  );
  Expect.isNull(getterFunctionReturnsUndefined());
  getterFunction = getterFunctionReturnsUndefined;
  Expect.isNull(getterFunction());

  eval(r'self.nullField = null;');
  Expect.throwsTypeErrorWhen(checksEnabled, () => nullField);
  Expect.throwsTypeErrorWhen(checksEnabled, () => undefinedField);

  eval(r'self.nullableFunction = function() { return null; };');
  Expect.isNull(nullableFunction());

  eval(r'self.nullableGetter = null;');
  Expect.isNull(nullableGetter);

  eval(r'self.nullableField = null;');
  Expect.isNull(nullableField);
}

void inlinedTopLevelMemberTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  eval(r'self.returnsNullInlined = function() { return null; }');
  Expect.throwsTypeErrorWhen(checksEnabled, () => returnsNullInlined());

  eval(r'self.returnsUndefinedInlined = function() { return void 0; }');
  Expect.throwsTypeErrorWhen(checksEnabled, () => returnsUndefinedInlined());

  var functionTearoff = returnsNullInlined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  functionTearoff = returnsUndefinedInlined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());

  eval(r'self.getsNullInlined = null;');
  Expect.throwsTypeErrorWhen(checksEnabled, () => getsNullInlined);
  Expect.throwsTypeErrorWhen(checksEnabled, () => undefinedGetterInlined);

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  eval(r'self.getterFunctionReturnsNullInlined = function() { return null; };');
  Expect.isNull(getterFunctionReturnsNullInlined());
  var getterFunction = getterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());

  eval(
    r'self.getterFunctionReturnsUndefinedInlined = function() { '
    'return void 0; };',
  );
  Expect.isNull(getterFunctionReturnsUndefinedInlined());
  getterFunction = getterFunctionReturnsUndefinedInlined;
  Expect.isNull(getterFunction());

  eval(r'self.nullFieldInlined = null;');
  Expect.throwsTypeErrorWhen(checksEnabled, () => nullFieldInlined);
  Expect.throwsTypeErrorWhen(checksEnabled, () => undefinedFieldInlined);

  eval(r'self.nullableFunctionInlined = function() { return null; };');
  Expect.isNull(nullableFunctionInlined());

  eval(r'self.nullableGetterInlined = null;');
  Expect.isNull(nullableGetterInlined);

  eval(r'self.nullableFieldInlined = null;');
  Expect.isNull(nullableFieldInlined);
}

void anonymousClassSetup() {
  eval(r'''self.createSomeClass = function() {
        return {
          "returnsNull": function() { return null; },
          "returnsNullInlined": function() { return null; },
          "returnsUndefined": function() { return void 0; },
          "returnsUndefinedInlined": function() { return void 0; },
          "getsNull" : null,
          "getsNullInlined" : null,
          "jsGetsNull": { get: function() { return null; } },
          "jsGetsNullInlined": { get: function() { return null; } },
          "jsGetsUndefined": { get: function() { return void 0; } },
          "jsGetsUndefinedInlined": { get: function() { return void 0; } },
          "getterFunctionReturnsNull": function() { return null; },
          "getterFunctionReturnsNullInlined": function() { return null; },
          "getterFunctionReturnsUndefined": function() { return void 0; },
          "getterFunctionReturnsUndefinedInlined": function() { return void 0; },
          "nullField" : null,
          "nullFieldInlined" : null,
          "nullableFunction": function() { return null; },
          "nullableFunctionInlined": function() { return null; },
          "nullableGetter": null,
          "nullableGetterInlined": null,
          "nullableField": null,
          "nullableFieldInlined": null,
        };
      };
      ''');

  eval(r'''self.AnotherClass = class AnotherClass {
          static staticReturnsNull() { return null; }
          static staticReturnsNullInlined() { return null; }
          static staticReturnsUndefined() { return void 0; }
          static staticReturnsUndefinedInlined() { return void 0; }
          static get staticGetsNull() { return null; }
          static get staticGetsNullInlined() { return null; }
          static get staticGetterFunctionReturnsNull() {
            return function() { return null; };
          }
          static get staticGetterFunctionReturnsNullInlined() {
            return function() { return null; };
          }
          static get staticGetterFunctionReturnsUndefined() {
            return function() { return void 0; };
          }
          static get staticGetterFunctionReturnsUndefinedInlined() {
            return function() { return void 0; };
          }
          static staticNullableFunction() { return null; }
          static staticNullableFunctionInlined() { return null; }
          static get staticNullableGetter() { return null; }
          static get staticNullableGetterInlined() { return null; }
          static staticNullableField = null;
          static staticNullableFieldInlined = null;
      };''');
}

void anonymousClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  var x = createSomeClass();
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.returnsNull());
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.returnsUndefined());

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = x.returnsNull;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());
  functionTearoff = x.returnsUndefined;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());

  Expect.throwsTypeErrorWhen(checksEnabled, () => x.getsNull);
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.undefinedGetter);

  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => x.getterFunctionReturnsNull(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => x.getterFunctionReturnsUndefined(),
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = x.getterFunctionReturnsNull;
  Expect.isNull(getterFunction());
  getterFunction = x.getterFunctionReturnsUndefined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(checksEnabled, () => x.nullField);
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.undefinedField);

  Expect.isNull(x.nullableFunction());
  Expect.isNull(x.nullableGetter);
  Expect.isNull(x.nullableField);

  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticReturnsNull(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticReturnsUndefined(),
  );
  functionTearoff = AnotherClass.staticReturnsNull;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  functionTearoff = AnotherClass.staticReturnsUndefined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  Expect.throwsTypeErrorWhen(checksEnabled, () => AnotherClass.staticGetsNull);
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticUndefinedGetter,
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  Expect.isNull(AnotherClass.staticGetterFunctionReturnsNull());
  Expect.isNull(AnotherClass.staticGetterFunctionReturnsUndefined());
  getterFunction = AnotherClass.staticGetterFunctionReturnsNull;
  Expect.isNull(getterFunction());
  getterFunction = AnotherClass.staticGetterFunctionReturnsUndefined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(checksEnabled, () => AnotherClass.staticNullField);
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticUndefinedField,
  );

  Expect.isNull(AnotherClass.staticNullableFunction());
  Expect.isNull(AnotherClass.staticNullableGetter);
  Expect.isNull(AnotherClass.staticNullableField);
}

void inlinedAnonymousClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  var x = createSomeClass();
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.returnsNullInlined());
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.returnsUndefinedInlined());

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = x.returnsNullInlined;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());
  functionTearoff = x.returnsUndefinedInlined;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());

  Expect.throwsTypeErrorWhen(checksEnabled, () => x.getsNullInlined);
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.undefinedGetterInlined);

  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => x.getterFunctionReturnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => x.getterFunctionReturnsUndefinedInlined(),
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = x.getterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());
  getterFunction = x.getterFunctionReturnsUndefinedInlined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(checksEnabled, () => x.nullFieldInlined);
  Expect.throwsTypeErrorWhen(checksEnabled, () => x.undefinedFieldInlined);

  Expect.isNull(x.nullableFunctionInlined());
  Expect.isNull(x.nullableGetterInlined);
  Expect.isNull(x.nullableFieldInlined);

  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticReturnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticReturnsUndefinedInlined(),
  );
  functionTearoff = AnotherClass.staticReturnsNullInlined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  functionTearoff = AnotherClass.staticReturnsUndefinedInlined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticGetsNullInlined,
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticUndefinedGetterInlined,
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  Expect.isNull(AnotherClass.staticGetterFunctionReturnsNullInlined());
  Expect.isNull(AnotherClass.staticGetterFunctionReturnsUndefinedInlined());
  getterFunction = AnotherClass.staticGetterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());
  getterFunction = AnotherClass.staticGetterFunctionReturnsUndefinedInlined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticNullFieldInlined,
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => AnotherClass.staticUndefinedFieldInlined,
  );

  Expect.isNull(AnotherClass.staticNullableFunctionInlined());
  Expect.isNull(AnotherClass.staticNullableGetterInlined);
  Expect.isNull(AnotherClass.staticNullableFieldInlined);
}

// DDC does not perform checks for dynamic invocations.
void dynamicAnonymousClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  obj = createSomeClass();
  Expect.throwsTypeErrorWhen(dart2js && checksEnabled, () => obj.returnsNull());
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.returnsUndefined(),
  );

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = obj.returnsNull;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());
  functionTearoff = obj.returnsUndefined;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());

  Expect.throwsTypeErrorWhen(dart2js && checksEnabled, () => obj.getsNull);
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedGetter,
  );

  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsNull(),
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsUndefined(),
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = obj.getterFunctionReturnsNull;
  Expect.isNull(getterFunction());
  getterFunction = obj.getterFunctionReturnsUndefined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(dart2js && checksEnabled, () => obj.nullField);
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedField,
  );

  Expect.isNull(obj.nullableFunction());
  Expect.isNull(obj.nullableGetter);
  Expect.isNull(obj.nullableField);
}

// DDC does not perform checks for dynamic invocations.
void dynamicInlinedAnonymousClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  obj = createSomeClass();
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.returnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.returnsUndefinedInlined(),
  );

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = obj.returnsNullInlined;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());
  functionTearoff = obj.returnsUndefinedInlined;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());

  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getsNullInlined,
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedGetterInlined,
  );

  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsUndefinedInlined(),
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = obj.getterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());
  getterFunction = obj.getterFunctionReturnsUndefinedInlined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.nullFieldInlined,
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedFieldInlined,
  );

  Expect.isNull(obj.nullableFunctionInlined());
  Expect.isNull(obj.nullableGetterInlined);
  Expect.isNull(obj.nullableFieldInlined);
}

void namedClassSetup() {
  eval(r'''self.NamedClass = class NamedClass {
          returnsNull() { return null; }
          returnsNullInlined() { return null; }
          returnsUndefined() { return void 0; }
          returnsUndefinedInlined() { return void 0; }
          static staticReturnsNull() { return null; }
          static staticReturnsNullInlined() { return null; }
          static staticReturnsUndefined() { return void 0; }
          static staticReturnsUndefinedInlined() { return void 0; }
          get getsNull() { return null; }
          get getsNullInlined() { return null; }
          static get staticGetsNull() { return null; }
          static get staticGetsNullInlined() { return null; }
          get getterFunctionReturnsNull() {
            return function() { return null; };
          }
          get getterFunctionReturnsNullInlined() {
            return function() { return null; };
          }
          get getterFunctionReturnsUndefined() {
            return function() { return void 0; };
          }
          get getterFunctionReturnsUndefinedInlined() {
            return function() { return void 0; };
          }
          static get staticGetterFunctionReturnsNull() {
            return function() { return null; };
          }
          static get staticGetterFunctionReturnsNullInlined() {
            return function() { return null; };
          }
          static get staticGetterFunctionReturnsUndefined() {
            return function() { return void 0; };
          }
          static get staticGetterFunctionReturnsUndefinedInlined() {
            return function() { return void 0; };
          }
          nullableFunction() { return null; }
          nullableFunctionInlined() { return null; }
          get nullableGetter() { return null; }
          get nullableGetterInlined() { return null; }
          nullableField = null;
          nullableFieldInlined = null;
          static staticNullableFunction() { return null; }
          static staticNullableFunctionInlined() { return null; }
          static get staticNullableGetter() { return null; }
          static get staticNullableGetterInlined() { return null; }
          static staticNullableField = null;
          static staticNullableFieldInlined = null;
          static createNamedClass() { return new NamedClass(); }
      };''');
}

void namedClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  var y = NamedClass.createNamedClass();
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.returnsNull());
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.returnsUndefined());

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = y.returnsNull;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());
  functionTearoff = y.returnsUndefined;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());

  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticReturnsNull(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticReturnsUndefined(),
  );
  functionTearoff = NamedClass.staticReturnsNull;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  functionTearoff = NamedClass.staticReturnsUndefined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.getsNull);
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.undefinedGetter);
  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => y.getterFunctionReturnsNull(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => y.getterFunctionReturnsUndefined(),
  );
  Expect.throwsTypeErrorWhen(checksEnabled, () => NamedClass.staticGetsNull);
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticUndefinedGetter,
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = y.getterFunctionReturnsNull;
  Expect.isNull(getterFunction());
  getterFunction = y.getterFunctionReturnsNull;
  Expect.isNull(getterFunction());
  Expect.isNull(NamedClass.staticGetterFunctionReturnsNull());
  Expect.isNull(NamedClass.staticGetterFunctionReturnsUndefined());
  getterFunction = NamedClass.staticGetterFunctionReturnsNull;
  Expect.isNull(getterFunction());
  getterFunction = NamedClass.staticGetterFunctionReturnsUndefined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(checksEnabled, () => y.nullField);
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.undefinedField);
  Expect.throwsTypeErrorWhen(checksEnabled, () => NamedClass.staticNullField);
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticUndefinedField,
  );

  Expect.isNull(y.nullableFunction());
  Expect.isNull(y.nullableGetter);
  Expect.isNull(y.nullableField);
  Expect.isNull(NamedClass.staticNullableFunction());
  Expect.isNull(NamedClass.staticNullableGetter);
  Expect.isNull(NamedClass.staticNullableField);
}

void inlinedNamedClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  var y = NamedClass.createNamedClass();
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.returnsNullInlined());
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.returnsUndefinedInlined());

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = y.returnsNullInlined;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());
  functionTearoff = y.returnsUndefinedInlined;
  Expect.throwsTypeErrorWhen(ddc && checksEnabled, () => functionTearoff());

  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticReturnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticReturnsUndefinedInlined(),
  );
  functionTearoff = NamedClass.staticReturnsNullInlined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  functionTearoff = NamedClass.staticReturnsUndefinedInlined;
  Expect.throwsTypeErrorWhen(checksEnabled, () => functionTearoff());
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.getsNullInlined);
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.undefinedGetterInlined);
  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => y.getterFunctionReturnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => y.getterFunctionReturnsUndefinedInlined(),
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticGetsNullInlined,
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticUndefinedGetterInlined,
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = y.getterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());
  getterFunction = y.getterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());
  Expect.isNull(NamedClass.staticGetterFunctionReturnsNullInlined());
  Expect.isNull(NamedClass.staticGetterFunctionReturnsUndefinedInlined());
  getterFunction = NamedClass.staticGetterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());
  getterFunction = NamedClass.staticGetterFunctionReturnsUndefinedInlined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(checksEnabled, () => y.nullFieldInlined);
  Expect.throwsTypeErrorWhen(checksEnabled, () => y.undefinedFieldInlined);
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticNullFieldInlined,
  );
  Expect.throwsTypeErrorWhen(
    checksEnabled,
    () => NamedClass.staticUndefinedFieldInlined,
  );

  Expect.isNull(y.nullableFunctionInlined());
  Expect.isNull(y.nullableGetterInlined);
  Expect.isNull(y.nullableFieldInlined);
  Expect.isNull(NamedClass.staticNullableFunctionInlined());
  Expect.isNull(NamedClass.staticNullableGetterInlined);
  Expect.isNull(NamedClass.staticNullableFieldInlined);
}

// DDC does not perform checks for dynamic invocations.
void dynamicNamedClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  obj = NamedClass.createNamedClass();
  Expect.throwsTypeErrorWhen(dart2js && checksEnabled, () => obj.returnsNull());
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.returnsUndefined(),
  );

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = obj.returnsNull;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());
  functionTearoff = obj.returnsUndefined;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());

  Expect.throwsTypeErrorWhen(dart2js && checksEnabled, () => obj.getsNull);
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedGetter,
  );
  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsNull(),
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsUndefined(),
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = obj.getterFunctionReturnsNull;
  Expect.isNull(getterFunction());
  getterFunction = obj.getterFunctionReturnsNull;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(dart2js && checksEnabled, () => obj.nullField);
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedField,
  );

  Expect.isNull(obj.nullableFunction());
  Expect.isNull(obj.nullableGetter);
  Expect.isNull(obj.nullableField);
}

// DDC does not perform checks for dynamic invocations.
void dynamicInlinedNamedClassTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  obj = NamedClass.createNamedClass();
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.returnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.returnsUndefinedInlined(),
  );

  // In dart2js, a tearoff of an interop method is indistinguishable from a
  // getter returning the underlying function.
  var functionTearoff = obj.returnsNullInlined;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());
  functionTearoff = obj.returnsUndefinedInlined;
  Expect.throwsTypeErrorWhen(false, () => functionTearoff());

  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getsNullInlined,
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedGetterInlined,
  );
  // Immediate invocations of instance getters are seen as function calls so
  // the results get checked.
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsNullInlined(),
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.getterFunctionReturnsUndefinedInlined(),
  );

  // At the time this test was written, getters that return function types don't
  // get the same wrappers as function tearoffs so there isn't an opportunity to
  // check the return values so they can still leak null or undefined through
  // from the JavaScript side.
  var getterFunction = obj.getterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());
  getterFunction = obj.getterFunctionReturnsNullInlined;
  Expect.isNull(getterFunction());

  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.nullFieldInlined,
  );
  Expect.throwsTypeErrorWhen(
    dart2js && checksEnabled,
    () => obj.undefinedFieldInlined,
  );

  Expect.isNull(obj.nullableFunctionInlined());
  Expect.isNull(obj.nullableGetterInlined);
  Expect.isNull(obj.nullableFieldInlined);
}

@JS()
class CollisionA {
  @pragma('dart2js:prefer-inline')
  external String foo([int? x]);

  @pragma('dart2js:never-inline')
  external String bar([int? x]);

  external factory CollisionA.create();
}

@JS()
class CollisionB {
  @pragma('dart2js:prefer-inline')
  external String? foo();

  @pragma('dart2js:never-inline')
  external String? bar();

  external factory CollisionB.create();
}

void collisionClassSetup() {
  eval(r'''
      self.CollisionA = class CollisionA {
        foo(x) { return null; }
        bar(x) { return null; }
        static create() { return new CollisionA(); }
      };

      self.CollisionB = class CollisionB {
        foo() { return null; }
        bar() { return null; }
        static create() { return new CollisionB(); }
      };''');
}

void collisionTests({required bool checksEnabled}) {
  // Provide at least one nullable value to [Expect.isNull] so that dart2js
  // doesn't discard the branch.
  Expect.isNull(null);

  var a = CollisionA.create();
  var b = CollisionB.create();

  // In dart2js, the receiver type is erased to `LegacyJavaScriptObject`, so we
  // cannot identify which class's method is being invoked and cannot emit a
  // null check. DDC is able to identify the member being invoked.
  Expect.throwsTypeErrorWhen(checksEnabled && ddc, () => a.foo());
  Expect.throwsTypeErrorWhen(checksEnabled && ddc, () => a.bar());

  Expect.isNull(b.foo());
  Expect.isNull(b.bar());

  // Because `foo$1` and `bar$1` only exist for [CollisionA] and not
  // [CollisionB], dart2js still emits these checks in the callee.
  Expect.throwsTypeErrorWhen(checksEnabled, () => a.foo(42));
  Expect.throwsTypeErrorWhen(checksEnabled, () => a.bar(42));
}

void runTests({required bool checksEnabled}) {
  topLevelMemberTests(checksEnabled: checksEnabled);
  inlinedTopLevelMemberTests(checksEnabled: checksEnabled);

  anonymousClassSetup();
  anonymousClassTests(checksEnabled: checksEnabled);
  inlinedAnonymousClassTests(checksEnabled: checksEnabled);
  dynamicAnonymousClassTests(checksEnabled: checksEnabled);
  dynamicInlinedAnonymousClassTests(checksEnabled: checksEnabled);

  namedClassSetup();
  namedClassTests(checksEnabled: checksEnabled);
  inlinedNamedClassTests(checksEnabled: checksEnabled);
  dynamicNamedClassTests(checksEnabled: checksEnabled);
  dynamicInlinedNamedClassTests(checksEnabled: checksEnabled);

  collisionClassSetup();
  collisionTests(checksEnabled: checksEnabled);
}
