[dart2js] Fix native null assertions for Dart 3

Allows the following semantics:
- If the disable flag is passed, never check
- If we're in non-sound mode, never check to avoid a breaking
change (this was the behavior before)
- If the enable flag was passed and we're in sound mode,
always check
- If we're in sound mode and with >= -03, don't check

Discussion in https://github.com/dart-lang/sdk/issues/50710

Change-Id: If83aaebb2745e4c8bcaa3f5a38ff41d79a869b8b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/289451
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Srujan Gaddam <srujzs@google.com>
This commit is contained in:
Srujan Gaddam 2023-04-03 18:05:28 +00:00 committed by Commit Queue
parent 71b0bb3473
commit e95b84ed41
8 changed files with 107 additions and 1 deletions

View file

@ -194,6 +194,19 @@
#### Web Dev Compiler (DDC)
- Removed deprecated command line flags `-k`, `--kernel`, and `--dart-sdk`.
- The compile time flag `--nativeNonNullAsserts`, which ensures web library APIs
are sound in their nullability, is by default set to true in sound mode. For
more information on the flag, see [NATIVE_NULL_ASSERTIONS.md][].
[NATIVE_NULL_ASSERTIONS.md]: https://github.com/dart-lang/sdk/blob/main/sdk/lib/html/doc/NATIVE_NULL_ASSERTIONS.md
#### dart2js
- The compile time flag `--native-null-assertions`, which ensures web library
APIs are sound in their nullability, is by default set to true in sound mode,
unless `-O3` or higher is passed, in which case they are not checked. For more
information on the flag, see [NATIVE_NULL_ASSERTIONS.md][].
[NATIVE_NULL_ASSERTIONS.md]: https://github.com/dart-lang/sdk/blob/main/sdk/lib/html/doc/NATIVE_NULL_ASSERTIONS.md
#### Dart2js

View file

@ -1287,6 +1287,11 @@ Usage: dart compile js [arguments] <dart entry point>
dart2js to generate smaller code by removing late variable names from the
generated JavaScript.
--native-null-assertions
Add assertions to web library APIs to ensure that non-nullable APIs do not
return null. This is by default set to true in sound null-safety, unless
-O3 or higher is passed.
-O<0,1,2,3,4>
Controls optimizations that can help reduce code-size and improve
performance of the generated code for deployment.

View file

@ -832,8 +832,21 @@ class CompilerOptions implements DiagnosticOptions {
omitLateNames = false;
}
if (_noNativeNullAssertions || nullSafetyMode != NullSafetyMode.sound) {
if (nullSafetyMode != NullSafetyMode.sound) {
// Technically, we should still assert if the user passed in a flag to
// assert, but this was not the behavior before, so to avoid a breaking
// change, we don't assert in unsound mode.
nativeNullAssertions = false;
} else if (_noNativeNullAssertions) {
// Never assert if the user tells us not to.
nativeNullAssertions = false;
} else if (!nativeNullAssertions &&
(optimizationLevel != null && optimizationLevel! >= 3)) {
// If the user didn't tell us to assert and we're in >= -O3, optimize away
// the check. This should reduce issues in production.
nativeNullAssertions = false;
} else {
nativeNullAssertions = true;
}
if (_mergeFragmentsThreshold != null) {

View file

@ -37,6 +37,15 @@ Native null assertions will be turned on by default across different build
systems. If it is enabled, here's how you can disable it in the following build
systems:
### dart2js
Pass the `--no-native-null-assertions` flag to dart2js. Note that in dart2js,
we turn off native null assertions when `-O3` or higher is specified.
### DDC
Set `nativeNonNullAsserts` to false.
### build_web_compilers
https://github.com/dart-lang/build/tree/master/docs/native_null_assertions.md

View file

@ -0,0 +1,16 @@
// 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.
// Requirements=nnbd-strong
// dart2jsOptions=-O3 --native-null-assertions
import 'null_assertions_test_lib.dart';
import 'web_library_interfaces.dart';
void main() {
// If the user explicitly passes the flag, we can't optimize the check away.
var flagEnabled = true;
testNativeNullAssertions(flagEnabled);
testJSInvocationNullAssertions(flagEnabled);
}

View file

@ -0,0 +1,17 @@
// 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.
// Requirements=nnbd-weak
// dart2jsOptions=--native-null-assertions
import 'null_assertions_test_lib.dart';
import 'web_library_interfaces.dart';
void main() {
// To avoid a breaking change, we don't enable checks even if the user passes
// the flag in unsound mode.
var flagEnabled = false;
testNativeNullAssertions(flagEnabled);
testJSInvocationNullAssertions(flagEnabled);
}

View file

@ -0,0 +1,16 @@
// 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.
// Requirements=nnbd-strong
// dart2jsOptions=-O3
import 'null_assertions_test_lib.dart';
import 'web_library_interfaces.dart';
void main() {
// If the flag wasn't passed, we can optimize the check away.
var flagEnabled = false;
testNativeNullAssertions(flagEnabled);
testJSInvocationNullAssertions(flagEnabled);
}

View file

@ -0,0 +1,17 @@
// 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.
// Requirements=nnbd-strong
// dart2jsOptions=-O1
import 'null_assertions_test_lib.dart';
import 'web_library_interfaces.dart';
void main() {
// Strong mode should enable checks in the default optimization level if
// neither the enable or disable flag is passed.
var flagEnabled = true;
testNativeNullAssertions(flagEnabled);
testJSInvocationNullAssertions(flagEnabled);
}