| // 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. | |
| import '../native_testing.dart'; | |
| import 'null_assertions_test_lib.dart'; | |
| // Implementations of `NativeInterface` and `JSInterface` in a folder that is | |
| // not part of the allowlist for the `--native-null-assertions` flag. This file | |
| // is not treated as a web library, and therefore native members and `JS()` | |
| // invocations should not be checked. | |
| @Native("AAA") | |
| class AAA implements NativeInterface { | |
| int get size native; | |
| String get name native; | |
| String? get optName native; | |
| int method1() native; | |
| String method2() native; | |
| String? optMethod() native; | |
| } | |
| @Native('CCC') | |
| class CCC implements JSInterface { | |
| String get name => JS('String', '#.name', this); | |
| String? get optName => JS('String|Null', '#.optName', this); | |
| } | |
| /// Returns an 'AAA' object that satisfies the interface. | |
| AAA makeA() native; | |
| /// Returns an 'AAA' object where each method breaks the interface's contract. | |
| AAA makeAX() native; | |
| /// Returns a 'CCC' object that satisfies the interface using `JS()` | |
| /// invocations. | |
| CCC makeC() native; | |
| /// Returns a 'CCC' object where each method breaks the interface's contract. | |
| CCC makeCX() native; | |
| // The 'AAA' version of the code is passed only objects of a single native | |
| // class, so the native method can be inlined (which happens in the optimizer). | |
| // This tests that the null-check exists in the 'inlined' code. | |
| @pragma('dart2js:noInline') | |
| String describeAAA(AAA o) { | |
| return '${o.name} ${o.method2()} ${o.size} ${o.method1()}'; | |
| } | |
| @pragma('dart2js:noInline') | |
| String describeOptAAA(AAA o) { | |
| return '${o.optName} ${o.optMethod()}'; | |
| } | |
| void testNativeNullAssertions(bool flagEnabled) { | |
| nativeTesting(); | |
| setup(); | |
| AAA a = makeA(); | |
| BBB b = BBB(); | |
| Expect.equals(expectedA, describeNativeInterface(a)); | |
| Expect.equals(expectedB, describeNativeInterface(b)); | |
| Expect.equals(expectedA, describeAAA(a)); | |
| AAA x = makeAX(); // This object returns `null`! | |
| // Since native members are not in a web library, there should be no checks, | |
| // regardless of if the flag is enabled. | |
| var checkExpectation = (f) => f(); | |
| checkExpectation(() => describeNativeInterface(x)); | |
| checkExpectation(() => describeAAA(x)); | |
| checkExpectation(() => x.name); | |
| checkExpectation(() => x.size); | |
| checkExpectation(() => x.method1()); | |
| checkExpectation(() => x.method2()); | |
| // Now test that a nullable return type does not have a check. | |
| Expect.equals(expectedOptA, describeOptNativeInterface(a)); | |
| Expect.equals(expectedOptB, describeOptNativeInterface(b)); | |
| Expect.equals(expectedOptX, describeOptNativeInterface(x)); | |
| Expect.equals(expectedOptA, describeOptAAA(a)); | |
| Expect.equals(expectedOptX, describeOptAAA(x)); | |
| } | |
| void testJSInvocationNullAssertions(bool flagEnabled) { | |
| nativeTesting(); | |
| setup(); | |
| CCC c = makeC(); | |
| CCC cx = makeCX(); | |
| Expect.equals(expectedC, describeJSInterface(c)); | |
| // Since invocations are not in a web library, there should be no checks, | |
| // regardless of if the flag is enabled. | |
| var checkExpectation = (f) => f(); | |
| checkExpectation(() => describeJSInterface(cx)); | |
| // Test that invocations with a nullable static type do not have checks. | |
| Expect.equals(expectedOptC, describeOptJSInterface(c)); | |
| Expect.equals(expectedOptCX, describeOptJSInterface(cx)); | |
| } |