6befc18cae
Change-Id: I2d3548eb609743277c026155d70fc1cb4d976cc7 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/143040 Reviewed-by: Erik Ernst <eernst@google.com>
317 lines
12 KiB
Dart
317 lines
12 KiB
Dart
// Copyright (c) 2020, 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.
|
|
|
|
// @dart=2.7
|
|
|
|
// Requirements=nnbd-weak
|
|
|
|
import 'package:expect/expect.dart';
|
|
import 'never_null_assignability_lib1.dart';
|
|
|
|
void takesLegacyObject(Object n) {
|
|
// In a legacy library, we may get null. Throw AssertionError so that this
|
|
// can be distinguished from a dynamic call failure.
|
|
if (n == null) throw AssertionError("Not an Object");
|
|
}
|
|
|
|
void takesLegacyInt(int n) {
|
|
// In a legacy library, we may get null. Throw AssertionError so that this
|
|
// can be distinguished from a dynamic call failure.
|
|
if (n == null) throw AssertionError("Not an int");
|
|
}
|
|
|
|
void takesLegacyNull(Null n) {
|
|
// This should never happen!
|
|
if (n != null) throw AssertionError("Not null");
|
|
}
|
|
|
|
// Tests for direct calls to null safe functions.
|
|
void testNullSafeCalls() {
|
|
// Test calling a null safe function expecting Null from a legacy library
|
|
{
|
|
takesNull(nil);
|
|
takesNull(never);
|
|
// Even in weak mode, 3 can't be cast to Null or Never
|
|
Expect.throwsTypeError(() => takesNull(3 as dynamic));
|
|
Expect.throwsTypeError(() => (takesNull as dynamic)(3));
|
|
}
|
|
|
|
// Test calling a null safe function expecting Never from a legacy library
|
|
{
|
|
takesNever(nil);
|
|
takesNever(never);
|
|
// Even in weak mode, 3 can't be cast to Null or Never
|
|
Expect.throwsTypeError(() => takesNever(3 as dynamic));
|
|
Expect.throwsTypeError(() => (takesNever as dynamic)(3));
|
|
}
|
|
|
|
// Test calling a null safe function expecting int from a legacy library
|
|
{
|
|
takesInt(3);
|
|
Expect.throwsAssertionError(() => takesInt(nil));
|
|
Expect.throwsAssertionError(() => takesInt(nil as dynamic));
|
|
Expect.throwsAssertionError(() => (takesInt as dynamic)(nil));
|
|
Expect.throwsTypeError(() => (takesInt as dynamic)("hello"));
|
|
}
|
|
|
|
// Test calling a null safe function expecting Object from a legacy library
|
|
{
|
|
takesObject(3);
|
|
Expect.throwsAssertionError(() => takesObject(nil));
|
|
Expect.throwsAssertionError(() => takesObject(nil as dynamic));
|
|
Expect.throwsAssertionError(() => (takesObject as dynamic)(nil));
|
|
}
|
|
|
|
// Test calling a null safe function expecting Object? from a legacy library
|
|
{
|
|
takesAny(3);
|
|
takesAny(nil);
|
|
(takesAny as dynamic)(nil);
|
|
}
|
|
}
|
|
|
|
// Tests for direct calls to legacy functions.
|
|
void testLegacyCalls() {
|
|
// Test calling a legacy function expecting Null from a legacy library
|
|
{
|
|
takesLegacyNull(nil);
|
|
// Even in weak mode, 3 can't be cast to Null or Never
|
|
Expect.throwsTypeError(() => takesLegacyNull(3 as dynamic));
|
|
Expect.throwsTypeError(() => (takesLegacyNull as dynamic)(3));
|
|
}
|
|
|
|
// Test calling a legacy function expecting int from a legacy library
|
|
{
|
|
takesLegacyInt(3);
|
|
Expect.throwsAssertionError(() => takesLegacyInt(nil));
|
|
Expect.throwsAssertionError(() => (takesLegacyInt as dynamic)(nil));
|
|
Expect.throwsTypeError(() => (takesLegacyInt as dynamic)("hello"));
|
|
}
|
|
|
|
// Test calling a legacy function expecting Object from a legacy library
|
|
{
|
|
takesLegacyObject(3);
|
|
Expect.throwsAssertionError(() => takesLegacyObject(nil));
|
|
Expect.throwsAssertionError(() => (takesLegacyObject as dynamic)(nil));
|
|
}
|
|
}
|
|
|
|
void testNullSafeApply() {
|
|
// Test applying a null safe function of static type void Function(Null)
|
|
// in a null safe library, when called with null cast to Null at the call
|
|
// site.
|
|
{
|
|
applyTakesNull(takesNull, nil);
|
|
applyTakesNull(takesNever, nil);
|
|
applyTakesNull(takesAny, nil);
|
|
|
|
// Cast of null to Null shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNull(takesInt, nil));
|
|
// Cast of null to Null shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNull(takesObject, nil));
|
|
}
|
|
|
|
// Test applying a null safe function of static type void Function(Null)
|
|
// in a null safe library, when called with a non-null value cast to Null
|
|
// at the call site.
|
|
{
|
|
Expect.throwsTypeError(() => applyTakesNull(takesNull, 3));
|
|
Expect.throwsTypeError(() => applyTakesNull(takesNever, 3));
|
|
Expect.throwsTypeError(() => applyTakesNull(takesInt, 3));
|
|
Expect.throwsTypeError(() => applyTakesNull(takesObject, 3));
|
|
Expect.throwsTypeError(() => applyTakesNull(takesAny, 3));
|
|
}
|
|
|
|
// Test applying a null safe function of static type void Function(Never)
|
|
// in a null safe library, when called with null cast to Never at the call
|
|
// site.
|
|
{
|
|
applyTakesNever(takesNull, nil);
|
|
applyTakesNever(takesNever, nil);
|
|
applyTakesNever(takesAny, nil);
|
|
|
|
// Cast of null to Never shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNever(takesInt, nil));
|
|
// Cast of null to Never shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNever(takesObject, nil));
|
|
}
|
|
|
|
// Test applying a null safe function of static type void Function(Never)
|
|
// in a null safe library, when called with a non-null value cast to Never
|
|
// at the call site.
|
|
{
|
|
Expect.throwsTypeError(() => applyTakesNever(takesNull, 3));
|
|
Expect.throwsTypeError(() => applyTakesNever(takesNever, 3));
|
|
Expect.throwsTypeError(() => applyTakesNever(takesInt, 3));
|
|
Expect.throwsTypeError(() => applyTakesNever(takesObject, 3));
|
|
Expect.throwsTypeError(() => applyTakesNever(takesAny, 3));
|
|
}
|
|
}
|
|
|
|
void testLegacyApply() {
|
|
// Test applying a legacy function of static type void Function(Null)
|
|
// in a null safe library, when called with null cast to Null at the call
|
|
// site.
|
|
{
|
|
applyTakesNull(takesLegacyNull, nil);
|
|
|
|
// Cast of null to Null shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNull(takesLegacyInt, nil));
|
|
// Cast of null to Null shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNull(takesLegacyObject, nil));
|
|
}
|
|
|
|
// Test applying a legacy function of static type void Function(Null)
|
|
// in a null safe library, when called with a non-null value cast to Null
|
|
// at the call site.
|
|
{
|
|
Expect.throwsTypeError(() => applyTakesNull(takesLegacyNull, 3));
|
|
Expect.throwsTypeError(() => applyTakesNull(takesLegacyInt, 3));
|
|
Expect.throwsTypeError(() => applyTakesNull(takesLegacyObject, 3));
|
|
}
|
|
|
|
// Test applying a legacy function of static type void Function(Never)
|
|
// in a null safe library, when called with null cast to Never at the call
|
|
// site.
|
|
{
|
|
applyTakesNever(takesLegacyNull, nil);
|
|
|
|
// Cast of null to Never shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNever(takesLegacyInt, nil));
|
|
// Cast of null to Never shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNever(takesLegacyObject, nil));
|
|
}
|
|
|
|
// Test applying a legacy function of static type void Function(Never)
|
|
// in a null safe library, when called with a non-null value cast to Never
|
|
// at the call site.
|
|
{
|
|
Expect.throwsTypeError(() => applyTakesNever(takesLegacyNull, 3));
|
|
Expect.throwsTypeError(() => applyTakesNever(takesLegacyInt, 3));
|
|
Expect.throwsTypeError(() => applyTakesNever(takesLegacyObject, 3));
|
|
}
|
|
}
|
|
|
|
void testNullSafeApplyDynamically() {
|
|
// Test dynamically applying a null safe function of static type
|
|
// void Function(Null) in a null safe library, when called with
|
|
// null.
|
|
{
|
|
applyTakesNullDynamically(takesNull, nil);
|
|
applyTakesNullDynamically(takesNever, nil);
|
|
applyTakesNullDynamically(takesAny, nil);
|
|
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(() => applyTakesNullDynamically(takesInt, nil));
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(
|
|
() => applyTakesNullDynamically(takesObject, nil));
|
|
}
|
|
|
|
// Test dynamically applying a null safe function of static type
|
|
// void Function(Null) in a null safe library, when called with
|
|
// a non-null value.
|
|
{
|
|
Expect.throwsTypeError(() => applyTakesNullDynamically(takesNull, 3));
|
|
Expect.throwsTypeError(() => applyTakesNullDynamically(takesNever, 3));
|
|
applyTakesNullDynamically(takesInt, 3);
|
|
Expect.throwsTypeError(() => applyTakesNullDynamically(takesInt, "hello"));
|
|
applyTakesNullDynamically(takesObject, 3);
|
|
applyTakesNullDynamically(takesAny, 3);
|
|
}
|
|
|
|
// Test dynamically applying a null safe function of static type
|
|
// void Function(Never) in a null safe library, when called with
|
|
// null.
|
|
{
|
|
applyTakesNeverDynamically(takesNull, nil);
|
|
applyTakesNeverDynamically(takesNever, nil);
|
|
applyTakesNeverDynamically(takesAny, nil);
|
|
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(
|
|
() => applyTakesNeverDynamically(takesInt, nil));
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(
|
|
() => applyTakesNeverDynamically(takesObject, nil));
|
|
}
|
|
|
|
// Test dynamically applying a null safe function of static type
|
|
// void Function(Never) in a null safe library, when called with
|
|
// a non-null value.
|
|
{
|
|
Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNull, 3));
|
|
Expect.throwsTypeError(() => applyTakesNeverDynamically(takesNever, 3));
|
|
applyTakesNeverDynamically(takesInt, 3);
|
|
Expect.throwsTypeError(() => applyTakesNeverDynamically(takesInt, "hello"));
|
|
applyTakesNeverDynamically(takesObject, 3);
|
|
applyTakesNeverDynamically(takesAny, 3);
|
|
}
|
|
}
|
|
|
|
void testLegacyApplyDynamically() {
|
|
// Test dynamically applying a legacy function of static type
|
|
// void Function(Null) in a null safe library, when called with
|
|
// null.
|
|
{
|
|
applyTakesNullDynamically(takesLegacyNull, nil);
|
|
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(
|
|
() => applyTakesNullDynamically(takesLegacyInt, nil));
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(
|
|
() => applyTakesNullDynamically(takesLegacyObject, nil));
|
|
}
|
|
|
|
// Test dynamically applying a legacy function of static type
|
|
// void Function(Null) in a null safe library, when called with
|
|
// a non-null value.
|
|
{
|
|
Expect.throwsTypeError(() => applyTakesNullDynamically(takesLegacyNull, 3));
|
|
applyTakesNullDynamically(takesLegacyInt, 3);
|
|
Expect.throwsTypeError(
|
|
() => applyTakesNullDynamically(takesLegacyInt, "hello"));
|
|
applyTakesNullDynamically(takesLegacyObject, 3);
|
|
}
|
|
|
|
// Test dynamically applying a legacy function of static type
|
|
// void Function(Never) in a null safe library, when called with
|
|
// null.
|
|
{
|
|
applyTakesNeverDynamically(takesLegacyNull, nil);
|
|
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(
|
|
() => applyTakesNeverDynamically(takesLegacyInt, nil));
|
|
// Dynamic call shouldn't fail, check that we reach the assertion.
|
|
Expect.throwsAssertionError(
|
|
() => applyTakesNeverDynamically(takesLegacyObject, nil));
|
|
}
|
|
|
|
// Test dynamically applying a legacy function of static type
|
|
// void Function(Never) in a null safe library, when called with
|
|
// a non-null value.
|
|
{
|
|
Expect.throwsTypeError(
|
|
() => applyTakesNeverDynamically(takesLegacyNull, 3));
|
|
applyTakesNeverDynamically(takesLegacyInt, 3);
|
|
Expect.throwsTypeError(
|
|
() => applyTakesNeverDynamically(takesLegacyInt, "hello"));
|
|
applyTakesNeverDynamically(takesLegacyObject, 3);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
never = null;
|
|
never = nil;
|
|
nil = never;
|
|
testNullSafeCalls();
|
|
testLegacyCalls();
|
|
testNullSafeApply();
|
|
testLegacyApply();
|
|
testNullSafeApplyDynamically();
|
|
testLegacyApplyDynamically();
|
|
}
|