Files
sdk/pkg/compiler/lib/src/commandline_options.dart
T
Mayank Patke ca3e67a3b6 [dart2js] Add --interop-null-assertions.
This CL adds a new --interop-null-assertions flag (cf.
--native-null-assertions) with the goal of validating that JS interop
APIs with non-nullable static return types do not return null values.
This flag is currently disabled by default but is intended to assist in
sound null safety migrations.

In general, we don't guarantee type soundness of package:js interop
since users can write incorrect static types which are not backed by
any runtime checks. However, it is likely that during the null safety
migration, some interop APIs which should have been made nullable
weren't. Therefore, we want to offer some additional (but limited)
checking for this case.

For static invocations of functions with non-nullable return types, we
can simply perform a null check on the result of the call.
For instance methods (which could be invoked virtually/dynamically), we
want to perform a null check on the return value in the callee (the
interceptor method) itself when possible.

It's possible for multiple interop bindings to share the same
interceptor method. We produce a null check in the interceptor method
body if all the methods have non-nullable return types. Otherwise, we
insert checks at callsites when appropriate.

Change-Id: Ifd155d7f8326152b6d57d61199e0b7973c4a1211
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/369784
Reviewed-by: Sigmund Cherem <sigmund@google.com>
Commit-Queue: Mayank Patke <fishythefish@google.com>
2024-06-12 21:28:23 +00:00

226 lines
10 KiB
Dart

// Copyright (c) 2015, 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.
library dart2js.cmdline.options;
/// Commandline flags used in `dart2js.dart` and/or `apiimpl.dart`.
class Flags {
// The uri of the main script file.
static const String entryUri = '--entry-uri';
// The uri of the main input dill.
static const String inputDill = '--input-dill';
static const String allowMockCompilation = '--allow-mock-compilation';
static const String allowNativeExtensions = '--allow-native-extensions';
static const String disableInlining = '--disable-inlining';
static const String disableProgramSplit = '--disable-program-split';
static const String disableDiagnosticColors = '--disable-diagnostic-colors';
static const String disableNativeLiveTypeAnalysis =
'--disable-native-live-type-analysis';
static const String useTrivialAbstractValueDomain =
'--use-trivial-abstract-value-domain';
static const String disableTypeInference = '--disable-type-inference';
static const String disableRtiOptimization = '--disable-rti-optimization';
static const String dumpInfo = '--dump-info';
static const String dumpInfoDataUri = '--dump-info-data';
static const String dumpDeferredGraph = '--dump-deferred-graph';
static const String deferredLoadIdMapUri = '--deferred-load-ids';
static const String dumpSsa = '--dump-ssa';
static const String enableAssertMessage = '--assert-message';
static const String enableCheckedMode = '--enable-checked-mode';
static const String enableAsserts = '--enable-asserts';
static const String enableNullAssertions = '--null-assertions';
static const String enableDiagnosticColors = '--enable-diagnostic-colors';
static const String experimentalTrackAllocations =
'--experimental-track-allocations';
static const String experimentalWrapped = '--experimental-wrapped';
static const String experimentalPowersets = '--experimental-powersets';
// Temporary experiment for code generation of locals for frequently used
// 'this' and constants.
static const String experimentLocalNames = '--experiment-code-1';
// Experimentally try to force part-file functions to be seen as IIFEs.
static const String experimentStartupFunctions = '--experiment-code-2';
// Experimentally rely on JavaScript ToBoolean conversions.
static const String experimentToBoolean = '--experiment-code-3';
// Experiment to make methods that are inferred as unreachable throw an
// exception rather than generate suspect code.
static const String experimentUnreachableMethodsThrow =
'--experiment-unreachable-throw';
// Add instrumentation to log every method call.
static const String experimentCallInstrumentation =
'--experiment-call-instrumentation';
static const String experimentNewRti = '--experiment-new-rti';
static const String experimentNullSafetyChecks =
'--experiment-null-safety-checks';
static const String enableLanguageExperiments = '--enable-experiment';
static const String fastStartup = '--fast-startup';
static const String fatalWarnings = '--fatal-warnings';
static const String generateCodeWithCompileTimeErrors =
'--generate-code-with-compile-time-errors';
static const String previewDart2 = '--preview-dart-2';
static const String omitImplicitChecks = '--omit-implicit-checks';
static const String omitAsCasts = '--omit-as-casts';
static const String laxRuntimeTypeToString = '--lax-runtime-type-to-string';
static const String enableProtoShaking = '--enable-proto-shaking';
static const String platformBinaries = '--platform-binaries=.+';
static const String minify = '--minify';
static const String noFrequencyBasedMinification =
'--no-frequency-based-minification';
// Disables minification even if enabled by other options, e.g. '-O2'.
static const String noMinify = '--no-minify';
static const String nativeNullAssertions = '--native-null-assertions';
static const String noNativeNullAssertions = '--no-native-null-assertions';
static const String interopNullAssertions = '--interop-null-assertions';
static const String noInteropNullAssertions = '--no-interop-null-assertions';
static const String noSourceMaps = '--no-source-maps';
static const String omitLateNames = '--omit-late-names';
static const String noOmitLateNames = '--no-omit-late-names';
static const String preserveUris = '--preserve-uris';
static const String printLegacyStars = '--debug-print-legacy-stars';
static const String showPackageWarnings = '--show-package-warnings';
static const String suppressHints = '--suppress-hints';
static const String suppressWarnings = '--suppress-warnings';
static const String terse = '--terse';
static const String testMode = '--test-mode';
static const String trustPrimitives = '--trust-primitives';
static const String trustTypeAnnotations = '--trust-type-annotations';
static const String trustJSInteropTypeAnnotations =
'--experimental-trust-js-interop-type-annotations';
static const String useMultiSourceInfo = '--use-multi-source-info';
static const String useNewSourceInfo = '--use-new-source-info';
static const String useOldRti = '--use-old-rti';
static const String useSimpleLoadIds = '--simple-load-ids';
static const String verbose = '--verbose';
static const String verbosity = '--verbosity';
static const String progress = '--show-internal-progress';
static const String version = '--version';
static const String reportMetrics = '--report-metrics';
static const String reportAllMetrics = '--report-all-metrics';
static const String dillDependencies = '--dill-dependencies';
static const String sources = '--sources';
static const String globalInferenceUri = '--global-inference-data';
static const String memoryMappedFiles = '--memory-map-files';
static const String closedWorldUri = '--closed-world-data';
static const String codegenUri = '--codegen-data';
static const String codegenShard = '--codegen-shard';
static const String codegenShards = '--codegen-shards';
static const String cfeOnly = '--cfe-only';
static const String stage = '--stage';
static const String debugGlobalInference = '--debug-global-inference';
static const String serverMode = '--server-mode';
static const String soundNullSafety = '--sound-null-safety';
static const String noSoundNullSafety = '--no-sound-null-safety';
static const String mergeFragmentsThreshold = '--merge-fragments-threshold';
static const String writeResources = '--write-resources';
/// Flag for a combination of flags for 'production' mode.
static const String benchmarkingProduction = '--benchmarking-production';
/// Flag for a combination of flags for benchmarking 'experiment' mode.
static const String benchmarkingExperiment = '--benchmarking-x';
static const String conditionalDirectives = '--conditional-directives';
static const String cfeInvocationModes = '--cfe-invocation-modes';
/// Flag to indicate how the compiler is invoked. Used to ensure
/// dart2js is only invoked from supported tools and through the Dart CLI.
static const String invoker = '--invoker';
/// Flag to stop after splitting the program.
static const String stopAfterProgramSplit = '--stop-after-program-split';
static const String writeProgramSplit = '--write-program-split';
static const String readProgramSplit = '--read-program-split';
// The syntax-only level of support for generic methods is included in the
// 1.50 milestone for Dart. It is not experimental, but also not permanent:
// a full implementation is expected in the future. Hence, the
// 'GENERIC_METHODS' comments which were added when this feature was
// experimental have been preserved, such that it will be easy to find the
// relevant locations to update when generic methods are implemented fully.
//
// The option is still accepted, but it has no effect: The feature is enabled
// by default and it cannot be disabled.
//
// The approach taken in the implementation is to parse generic methods,
// introduce AST nodes for them, generate corresponding types (such that
// front end treatment is consistent with the code that programmers wrote),
// but considering all method type variables to have bound `dynamic` no
// matter which bound they have syntactically (such that their value as types
// is unchecked), and then replacing method type variables by a `DynamicType`
// (such that the backend does not need to take method type arguments into
// account).
//
// The feature has an informal specification which is available at
// https://gist.github.com/eernstg/4353d7b4f669745bed3a5423e04a453c.
static const String genericMethodSyntax = '--generic-method-syntax';
// Initializing-formal access is enabled by default and cannot be disabled.
// For backward compatibility the option is still accepted, but it is ignored.
static const String initializingFormalAccess = '--initializing-formal-access';
// Whether or not to dump a list of unused libraries.
static const String dumpUnusedLibraries = '--dump-unused-libraries';
// Experimental flags.
static const String resolveOnly = '--resolve-only';
static const String cfeConstants = '--cfe-constants';
static const String disableDiagnosticByteCache =
'--disable-diagnostic-byte-cache';
// `--no-shipping` and `--canary` control sets of flags. For simplicity, these
// flags live in options.dart.
// Shipping features default to on, but can be disabled individually. All
// shipping features can be disabled with the [noShipping] flag.
static const String noShipping = '--no-shipping';
// Canary features default to off, but can still be enabled individually. All
// canary features can be enabled with the [canary] flag.
static const String canary = '--canary';
}
class Option {
static const String showPackageWarnings =
'${Flags.showPackageWarnings}|${Flags.showPackageWarnings}=.*';
static const String enableLanguageExperiments =
'${Flags.enableLanguageExperiments}|'
'${Flags.enableLanguageExperiments}=.*';
static const String multiRoots = '--multi-root=.+';
static const String multiRootScheme = '--multi-root-scheme=.+';
// Experimental options.
static const String resolutionInput = '--resolution-input=.+';
static const String bazelPaths = '--bazel-paths=.+';
}